Predicates.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. using Ant.Descriptors;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. using System.Reflection;
  8. using System.Text;
  9. namespace Ant.ORM
  10. {
  11. /// <summary>
  12. /// 自定义查询
  13. /// </summary>
  14. public static class Predicates
  15. {
  16. /// <summary>
  17. /// Factory method that creates a new IFieldPredicate predicate: [FieldName] [Operator] [Value].
  18. /// Example: WHERE FirstName = 'Foo'
  19. /// </summary>
  20. /// <typeparam name="T">The type of the entity.</typeparam>
  21. /// <param name="expression">An expression that returns the left operand [FieldName].</param>
  22. /// <param name="op">The comparison operator.</param>
  23. /// <param name="value">The value for the predicate.</param>
  24. /// <param name="not">Effectively inverts the comparison operator. Example: WHERE FirstName &lt;&gt; 'Foo'.</param>
  25. /// <returns>An instance of IFieldPredicate.</returns>
  26. public static IFieldPredicate QueryField<T>(Expression<Func<T, object>> expression, Operator op, object value, bool not = false) where T : class
  27. {
  28. PropertyInfo propertyInfo = ReflectionHelper.GetProperty(expression) as PropertyInfo;
  29. MetaData typeDesc = new MetaData();
  30. typeDesc.FiledMeta = MetaDataManager.GetMetaData(typeof(T));
  31. string strtable = typeof(T).Name;
  32. return new FieldPredicate<T>
  33. {
  34. TableName = typeDesc.FiledMeta.Table.Name,
  35. PropertyName = propertyInfo.Name,
  36. Operators = op,
  37. Value = value,
  38. Not = not
  39. };
  40. }
  41. /// <summary>
  42. /// Factory method that creates a new IPropertyPredicate predicate: [FieldName1] [Operator] [FieldName2]
  43. /// Example: WHERE FirstName = LastName
  44. /// </summary>
  45. /// <typeparam name="T">The type of the entity for the left operand.</typeparam>
  46. /// <typeparam name="T2">The type of the entity for the right operand.</typeparam>
  47. /// <param name="expression">An expression that returns the left operand [FieldName1].</param>
  48. /// <param name="op">The comparison operator.</param>
  49. /// <param name="expression2">An expression that returns the right operand [FieldName2].</param>
  50. /// <param name="not">Effectively inverts the comparison operator. Example: WHERE FirstName &lt;&gt; LastName </param>
  51. /// <returns>An instance of IPropertyPredicate.</returns>
  52. public static IPropertyPredicate Property<T, T2>(Expression<Func<T, object>> expression, Operator op, Expression<Func<T2, object>> expression2, bool not = false)
  53. where T : class
  54. where T2 : class
  55. {
  56. PropertyInfo propertyInfo = ReflectionHelper.GetProperty(expression) as PropertyInfo;
  57. PropertyInfo propertyInfo2 = ReflectionHelper.GetProperty(expression2) as PropertyInfo;
  58. return new PropertyPredicate<T, T2>
  59. {
  60. PropertyName = propertyInfo.Name,
  61. PropertyName2 = propertyInfo2.Name,
  62. Operators = op,
  63. Not = not
  64. };
  65. }
  66. /// <summary>
  67. /// 工厂方法创建一个新的ipredicategroup谓词。
  68. /// Factory method that creates a new IPredicateGroup predicate.
  69. /// Predicate groups can be joined together with other predicate groups.
  70. /// </summary>
  71. /// <param name="op">The grouping operator to use when joining the predicates (AND / OR).</param>
  72. /// <param name="predicate">A list of predicates to group.</param>
  73. /// <returns>An instance of IPredicateGroup.</returns>
  74. public static IPredicateGroup SqlGroup(GroupOperator op, params IPredicate[] predicate)
  75. {
  76. return new PredicateGroup
  77. {
  78. Operator = op,
  79. Predicates = predicate
  80. };
  81. }
  82. /// <summary>
  83. /// 把查询条件进行设置分组
  84. /// </summary>
  85. /// <param name="op"></param>
  86. /// <param name="predicate"></param>
  87. /// <returns></returns>
  88. public static IPredicateGroup SqlGroup(GroupOperator op, List<IPredicate> predicate)
  89. {
  90. return new PredicateGroup
  91. {
  92. Operator = op,
  93. Predicates = predicate
  94. };
  95. }
  96. /// <summary>
  97. /// Factory method that creates a new IExistsPredicate predicate.
  98. /// </summary>
  99. public static IExistsPredicate Exists<TSub>(IPredicate predicate, bool not = false)
  100. where TSub : class
  101. {
  102. string strtable = typeof(TSub).Name;
  103. return new ExistsPredicate<TSub>
  104. {
  105. Not = not,
  106. TableName = strtable,
  107. Predicate = predicate
  108. };
  109. }
  110. /// <summary>
  111. /// Factory method that creates a new IBetweenPredicate predicate.
  112. /// </summary>
  113. public static IBetweenPredicate Between<T>(Expression<Func<T, object>> expression, BetweenValues values, bool not = false)
  114. where T : class
  115. {
  116. PropertyInfo propertyInfo = ReflectionHelper.GetProperty(expression) as PropertyInfo;
  117. string strtable = typeof(T).Name;
  118. return new BetweenPredicate<T>
  119. {
  120. Not = not,
  121. TableName = (strtable.ToLower().StartsWith("ent")) ? strtable.Substring(3) : strtable,
  122. PropertyName = propertyInfo.Name,
  123. Value = values
  124. };
  125. }
  126. /// <summary>
  127. /// 工厂方法,创建一个新的排序,控制结果将如何排序
  128. /// Factory method that creates a new Sort which controls how the results will be sorted.
  129. /// </summary>
  130. public static ISort Sort<T>(Expression<Func<T, object>> expression, bool ascending = true)
  131. {
  132. PropertyInfo propertyInfo = ReflectionHelper.GetProperty(expression) as PropertyInfo;
  133. string strtable = typeof(T).Name;
  134. return new Sort
  135. {
  136. TableName = (strtable.ToLower().StartsWith("ent")) ? strtable.Substring(3) : strtable,
  137. PropertyName = propertyInfo.Name,
  138. Ascending = ascending
  139. };
  140. }
  141. }
  142. /// <summary>
  143. /// 自定义查询接口
  144. /// </summary>
  145. public interface IPredicate
  146. {
  147. string GetSql(FieldValueCollection filewhere, QueryCommand parameters);
  148. }
  149. public interface IBasePredicate : IPredicate
  150. {
  151. /// <summary>
  152. /// 表名
  153. /// </summary>
  154. string TableName { get; set; }
  155. /// <summary>
  156. /// 列名
  157. /// </summary>
  158. string PropertyName { get; set; }
  159. }
  160. public abstract class BasePredicate : IBasePredicate
  161. {
  162. /// <summary>
  163. /// 获取SQL语句
  164. /// </summary>
  165. /// <param name="md"></param>
  166. /// <param name="parameters"></param>
  167. /// <returns></returns>
  168. public abstract string GetSql(FieldValueCollection md, QueryCommand parameters);
  169. /// <summary>
  170. /// 列名
  171. /// </summary>
  172. public string PropertyName { get; set; }
  173. /// <summary>
  174. /// 表名
  175. /// </summary>
  176. public string TableName { get; set; }
  177. protected virtual string GetColumnName(Type entityType, string propertyName)
  178. {
  179. return "";
  180. //if (map == null)
  181. //{
  182. // throw new NullReferenceException(string.Format("Map was not found for {0}", entityType));
  183. //}
  184. //IPropertyMap propertyMap = map.Properties.SingleOrDefault(p => p.Name == propertyName);
  185. //if (propertyMap == null)
  186. //{
  187. // throw new NullReferenceException(string.Format("{0} was not found for {1}", propertyName, entityType));
  188. //}
  189. //return sqlGenerator.GetColumnName(map, propertyMap, false);
  190. }
  191. }
  192. public interface IComparePredicate : IBasePredicate
  193. {
  194. Operator Operators { get; set; }
  195. bool Not { get; set; }
  196. }
  197. public abstract class ComparePredicate : BasePredicate
  198. {
  199. public Operator Operators { get; set; }
  200. public bool Not { get; set; }
  201. public virtual string GetOperatorString()
  202. {
  203. switch (Operators)
  204. {
  205. case Operator.EqualSmaller:
  206. return Not ? "<=" : ">";
  207. case Operator.EqualLarger:
  208. return Not ? "<" : ">=";
  209. case Operator.Smaller:
  210. return Not ? ">=" : "<";
  211. case Operator.Larger:
  212. return Not ? ">" : "<=";
  213. case Operator.Like:
  214. return Not ? "NOT LIKE" : "LIKE";
  215. case Operator.NotEqual:
  216. return "<>";
  217. case Operator.Equal:
  218. return "=";
  219. case Operator.In:
  220. return "in";
  221. default:
  222. return Not ? "<>" : "=";
  223. }
  224. }
  225. }
  226. public interface IFieldPredicate : IComparePredicate
  227. {
  228. object Value { get; set; }
  229. }
  230. public class FieldPredicate<T> : ComparePredicate, IFieldPredicate
  231. where T : class
  232. {
  233. public object Value { get; set; }
  234. /// <summary>
  235. /// 获取拼接SQL语句
  236. /// </summary>
  237. /// <param name="parameters"></param>
  238. /// <returns></returns>
  239. public override string GetSql(FieldValueCollection md, QueryCommand parameters)
  240. {
  241. if (Value == null)
  242. {
  243. return string.Format("([{0}].{1} IS {2} NULL)", TableName, PropertyName, Not ? "NOT" : string.Empty);
  244. }
  245. if (Value is IEnumerable && !(Value is string))
  246. {
  247. List<string> paramlist = new List<string>();
  248. foreach (var value in (IEnumerable)Value)
  249. {
  250. string valueParameterName = parameters.SetParameterName(this.PropertyName, value, md);
  251. paramlist.Add(valueParameterName);
  252. }
  253. string paramStrings = paramlist.Aggregate(new StringBuilder(), (sb, s) => sb.Append((sb.Length != 0 ? ", " : string.Empty) + s), sb => sb.ToString());
  254. return string.Format("([{0}].{1} {2} IN ({3}))", TableName, PropertyName, Not ? "NOT " : string.Empty, paramStrings);
  255. }
  256. string parameterName = parameters.SetParameterName(this.PropertyName, this.Value, md);
  257. return string.Format("([{0}].{1} {2} {3})", TableName, PropertyName, GetOperatorString(), parameters.DbParmChar + parameterName);
  258. }
  259. }
  260. public interface IPropertyPredicate : IComparePredicate
  261. {
  262. string PropertyName2 { get; set; }
  263. }
  264. public class PropertyPredicate<T, T2> : ComparePredicate, IPropertyPredicate
  265. where T : class
  266. where T2 : class
  267. {
  268. public string PropertyName2 { get; set; }
  269. public override string GetSql(FieldValueCollection md, QueryCommand parameters)
  270. {
  271. string columnName = GetColumnName(typeof(T), PropertyName);
  272. string columnName2 = GetColumnName(typeof(T2), PropertyName2);
  273. return string.Format("({0} {1} {2})", columnName, GetOperatorString(), columnName2);
  274. }
  275. }
  276. #region BetweenAnd
  277. /// <summary>
  278. ///
  279. /// </summary>
  280. public struct BetweenValues
  281. {
  282. public object Value1 { get; set; }
  283. public object Value2 { get; set; }
  284. }
  285. public interface IBetweenPredicate : IPredicate
  286. {
  287. string PropertyName { get; set; }
  288. BetweenValues Value { get; set; }
  289. bool Not { get; set; }
  290. }
  291. /// <summary>
  292. ///
  293. /// </summary>
  294. /// <typeparam name="T"></typeparam>
  295. public class BetweenPredicate<T> : BasePredicate, IBetweenPredicate
  296. where T : class
  297. {
  298. public override string GetSql(FieldValueCollection md, QueryCommand parameters)
  299. {
  300. string propertyName1 = parameters.SetParameterName(this.PropertyName, this.Value.Value1, md);
  301. string propertyName2 = parameters.SetParameterName(this.PropertyName, this.Value.Value2, md);
  302. return string.Format("([{0}].{1} {2} BETWEEN {3} AND {4})", TableName, PropertyName, Not ? "NOT" : string.Empty, parameters.DbParmChar + propertyName1, parameters.DbParmChar + propertyName2);
  303. }
  304. public BetweenValues Value { get; set; }
  305. public bool Not { get; set; }
  306. }
  307. #endregion
  308. #region 查询条件分组
  309. public interface IPredicateGroup : IPredicate
  310. {
  311. GroupOperator Operator { get; set; }
  312. IList<IPredicate> Predicates { get; set; }
  313. }
  314. /// <summary>
  315. /// 组装Predicate一起使用指定的组操作
  316. /// </summary>
  317. public class PredicateGroup : IPredicateGroup
  318. {
  319. public GroupOperator Operator { get; set; }
  320. public IList<IPredicate> Predicates { get; set; }
  321. public string GetSql(FieldValueCollection md, QueryCommand parameters)
  322. {
  323. string seperator = Operator == GroupOperator.And ? " AND " : " OR ";
  324. List<string> colum = new List<string>();
  325. return "(" + Predicates.Aggregate(new StringBuilder(), (sb, p) => (sb.Length == 0 ? sb : sb.Append(seperator)).Append(p.GetSql(md, parameters)),
  326. sb =>
  327. {
  328. var s = sb.ToString();
  329. if (s.Length == 0) return "";
  330. return s;
  331. }) + ")";
  332. }
  333. }
  334. #endregion
  335. public interface IExistsPredicate : IPredicate
  336. {
  337. IPredicate Predicate { get; set; }
  338. bool Not { get; set; }
  339. }
  340. public class ExistsPredicate<TSub> : IExistsPredicate
  341. where TSub : class
  342. {
  343. public IPredicate Predicate { get; set; }
  344. /// <summary>
  345. /// 表名
  346. /// </summary>
  347. public string TableName { get; set; }
  348. /// <summary>
  349. /// 非
  350. /// </summary>
  351. public bool Not { get; set; }
  352. /// <summary>
  353. /// 获取拼接SQL语句
  354. /// </summary>
  355. /// <param name="md"></param>
  356. /// <param name="parameters"></param>
  357. /// <returns></returns>
  358. public string GetSql(FieldValueCollection md, QueryCommand parameters)
  359. {
  360. string sql = string.Format("({0}EXISTS (SELECT 1 FROM [{1}] WHERE {2}))", Not ? "NOT " : string.Empty, TableName, Predicate.GetSql(md, parameters));
  361. return sql;
  362. }
  363. }
  364. /// <summary>
  365. /// 排序接口定义
  366. /// </summary>
  367. public interface ISort
  368. {
  369. /// <summary>
  370. /// 表名
  371. /// </summary>
  372. string TableName { get; set; }
  373. /// <summary>
  374. /// 排序字段名
  375. /// </summary>
  376. string PropertyName { get; set; }
  377. /// <summary>
  378. /// 升序
  379. /// </summary>
  380. bool Ascending { get; set; }
  381. }
  382. public class Sort : ISort
  383. {
  384. /// <summary>
  385. /// 表名
  386. /// </summary>
  387. public string TableName { get; set; }
  388. /// <summary>
  389. /// 排序字段名
  390. /// </summary>
  391. public string PropertyName { get; set; }
  392. /// <summary>
  393. /// 升序
  394. /// </summary>
  395. public bool Ascending { get; set; }
  396. }
  397. /// <summary>
  398. /// 查询方式用and和or进行拼接枚举
  399. /// </summary>
  400. public enum GroupOperator
  401. {
  402. And,
  403. Or
  404. }
  405. }