EFCoreExt.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace wispro.sp.share
  8. {
  9. [Serializable]
  10. public class ExpressTree
  11. {
  12. private ConditionTreeNode root;
  13. public void AddCondition(LogicEnum logic, FieldCondition fieldCondition)
  14. {
  15. FieldConditionNode rightNode = new FieldConditionNode() { FieldCondition = fieldCondition };
  16. if (root == null)
  17. {
  18. Console.WriteLine("根节点为空时添加!");
  19. root = rightNode;
  20. }
  21. else
  22. {
  23. Console.WriteLine("根节点为空时添加!");
  24. OperateNode root1 = new OperateNode() { Operator = logic };
  25. Console.WriteLine("\t设定右节点!");
  26. root1.Right = rightNode;
  27. Console.WriteLine("\t设定左节点!");
  28. root1.Left = root;
  29. Console.WriteLine("\t设定根节点为操作节点!");
  30. root = root1;
  31. Console.WriteLine((root != null) ? "\t根节点不为空" : "\t根节点为空");
  32. }
  33. //Console.WriteLine($"表达式: {ToExpressString("s")}");
  34. }
  35. public string ToExpressString(string prefix)
  36. {
  37. if (root == null)
  38. {
  39. return null;
  40. }
  41. else
  42. {
  43. if (root is FieldConditionNode)
  44. {
  45. return ((FieldConditionNode)root).FieldCondition.ToExpressString(prefix);
  46. }
  47. else
  48. {
  49. OperateNode operate = (OperateNode)root;
  50. if (root.Right != null && root.Left != null)
  51. {
  52. ExpressTree leftTree = new ExpressTree() { root = root.Left };
  53. ExpressTree rightTree = new ExpressTree() { root = root.Right };
  54. switch (operate.Operator)
  55. {
  56. case LogicEnum.And:
  57. return $"({leftTree.ToExpressString(prefix)}) && ({rightTree.ToExpressString(prefix)})";
  58. break;
  59. case LogicEnum.Or:
  60. return $"({leftTree.ToExpressString(prefix)}) || ({rightTree.ToExpressString(prefix)})";
  61. break;
  62. default:
  63. return "";
  64. }
  65. }
  66. else
  67. {
  68. throw (new ApplicationException("无效的表达是树!"));
  69. }
  70. }
  71. }
  72. }
  73. }
  74. [Serializable]
  75. public class ConditionTreeNode
  76. {
  77. public ConditionTreeNode Right { get; set; }
  78. public ConditionTreeNode Left { get; set; }
  79. }
  80. [Serializable]
  81. public class OperateNode : ConditionTreeNode
  82. {
  83. public LogicEnum Operator { get; set; }
  84. }
  85. [Serializable]
  86. public class FieldConditionNode : ConditionTreeNode
  87. {
  88. public FieldCondition FieldCondition { get; set; }
  89. }
  90. [Serializable]
  91. public class OrderField
  92. {
  93. /// <summary>
  94. /// 排序栏位
  95. /// </summary>
  96. public string FieldName { get; set; }
  97. /// <summary>
  98. /// 排序 0:顺序;1:倒序
  99. /// </summary>
  100. public int Sort { get; set; }
  101. }
  102. [Serializable]
  103. public class FieldCondition
  104. {
  105. /// <summary>
  106. /// 字段名称
  107. /// </summary>
  108. public string FieldName { get; set; }
  109. /// <summary>
  110. /// 值
  111. /// </summary>
  112. public string Value { get; set; }
  113. /// <summary>
  114. /// 值类型
  115. /// </summary>
  116. public string ValueType { get; set; }
  117. /// <summary>
  118. ///
  119. /// </summary>
  120. public OperatorEnum Operator { get; set; }
  121. public LogicEnum LogicOperate { get; set; }
  122. public string ToExpressString(string prefix)
  123. {
  124. bool isString = (ValueType == typeof(string).ToString());
  125. switch (Operator)
  126. {
  127. case OperatorEnum.Contains:
  128. if (isString)
  129. {
  130. return $"{prefix}.{FieldName}.Contains(\"{Value.Trim()}\")";
  131. }
  132. else
  133. {
  134. throw (new ApplicationException("Contains 操作只对字符字段有效!"));
  135. }
  136. break;
  137. case OperatorEnum.NotContains:
  138. if (isString)
  139. {
  140. return $"!{prefix}.{FieldName}.Contains(\"{Value}\")";
  141. }
  142. else
  143. {
  144. throw (new ApplicationException("Contains 操作只对字符字段有效!"));
  145. }
  146. break;
  147. case OperatorEnum.Equal:
  148. if (isString)
  149. {
  150. return $"{prefix}.{FieldName} == (\"{Value}\")";
  151. }
  152. else
  153. {
  154. return $"{prefix}.{FieldName} == ({Value})";
  155. }
  156. break;
  157. case OperatorEnum.NotEqual:
  158. if (isString)
  159. {
  160. return $"{prefix}.{FieldName} != (\"{Value}\")";
  161. }
  162. else
  163. {
  164. return $"{prefix}.{FieldName} != ({Value})";
  165. }
  166. break;
  167. case OperatorEnum.Greater:
  168. if (isString)
  169. {
  170. return $"{prefix}.{FieldName} > (\"{Value}\")";
  171. }
  172. else
  173. {
  174. return $"{prefix}.{FieldName} > ({Value})";
  175. }
  176. break;
  177. case OperatorEnum.GreaterEqual:
  178. if (isString)
  179. {
  180. return $"{prefix}.{FieldName} >= (\"{Value}\")";
  181. }
  182. else
  183. {
  184. return $"{prefix}.{FieldName} >= ({Value})";
  185. }
  186. break;
  187. case OperatorEnum.Less:
  188. if (isString)
  189. {
  190. return $"{prefix}.{FieldName} < (\"{Value}\")";
  191. }
  192. else
  193. {
  194. return $"{prefix}.{FieldName} < ({Value})";
  195. }
  196. break;
  197. case OperatorEnum.LessEqual:
  198. if (isString)
  199. {
  200. return $"{prefix}.{FieldName} <= (\"{Value}\")";
  201. }
  202. else
  203. {
  204. return $"{prefix}.{FieldName} <= ({Value})";
  205. }
  206. break;
  207. case OperatorEnum.StartsWith:
  208. if (isString)
  209. {
  210. return $"{prefix}.{FieldName}.StartsWith(\"{Value}\")";
  211. }
  212. else
  213. {
  214. throw (new ApplicationException("StartsWith 操作只对字符字段有效!"));
  215. }
  216. break;
  217. case OperatorEnum.EndWith:
  218. if (isString)
  219. {
  220. return $"{prefix}.{FieldName}.EndWith(\"{Value}\")";
  221. }
  222. else
  223. {
  224. throw (new ApplicationException("EndWith 操作只对字符字段有效!"));
  225. }
  226. break;
  227. //case OperatorEnum.In:
  228. // break;
  229. //case OperatorEnum.Between:
  230. // break;
  231. default:
  232. throw (new ApplicationException("还未实现的操作符号!"));
  233. }
  234. }
  235. }
  236. [Serializable]
  237. public enum OperatorEnum
  238. {
  239. Contains,
  240. Equal,
  241. Greater,
  242. GreaterEqual,
  243. Less,
  244. LessEqual,
  245. NotEqual,
  246. In,
  247. Between,
  248. StartsWith,
  249. EndWith,
  250. NotContains
  251. }
  252. [Serializable]
  253. public enum LogicEnum
  254. {
  255. And,
  256. Or
  257. }
  258. public static class EFCoreExt
  259. {
  260. public static IQueryable<T> OrderConditions<T>(this IQueryable<T> query, IList<OrderField> orderConditions)
  261. {
  262. foreach (var orderinfo in orderConditions)
  263. {
  264. var parameter = Expression.Parameter(typeof(T));
  265. var prop = Expression.PropertyOrField(parameter, orderinfo.FieldName);
  266. var sortLambda = Expression.Lambda(prop, parameter);
  267. Expression<Func<IOrderedQueryable<T>>> sortMethod = (() => query.OrderBy<T, object>(k => null));
  268. if (orderinfo.Sort == 1)
  269. {
  270. sortMethod = (() => query.OrderByDescending<T, object>(k => null));
  271. }
  272. var methodCallExpression = (sortMethod.Body as MethodCallExpression);
  273. if (methodCallExpression == null)
  274. throw new Exception("Oops");
  275. var method = methodCallExpression.Method.GetGenericMethodDefinition();
  276. var genericSortMethod = method.MakeGenericMethod(typeof(T), prop.Type);
  277. query = (IQueryable<T>)genericSortMethod.Invoke(query, new object[] { query, sortLambda });
  278. }
  279. return query;
  280. }
  281. public static IOrderedQueryable<TEntityType> SortMeDynamically<TEntityType>(this IQueryable<TEntityType> query, string propertyname)
  282. {
  283. var param = Expression.Parameter(typeof(TEntityType), "s");
  284. var prop = Expression.PropertyOrField(param, propertyname);
  285. var sortLambda = Expression.Lambda(prop, param);
  286. Expression<Func<IOrderedQueryable<TEntityType>>> sortMethod = (() => query.OrderBy<TEntityType, object>(k => null));
  287. var methodCallExpression = (sortMethod.Body as MethodCallExpression);
  288. if (methodCallExpression == null)
  289. throw new Exception("Oops");
  290. var method = methodCallExpression.Method.GetGenericMethodDefinition();
  291. var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type);
  292. var orderedQuery = (IOrderedQueryable<TEntityType>)genericSortMethod.Invoke(query, new object[] { query, sortLambda });
  293. return orderedQuery;
  294. }
  295. public static IQueryable<T> Pager<T>(this IQueryable<T> query, int pageindex, int pagesize, out int itemCount)
  296. {
  297. itemCount = query.Count();
  298. return query.Skip((pageindex - 1) * pagesize).Take(pagesize);
  299. }
  300. }
  301. }