DynamicLinq.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. namespace TEAMModelOS.SDK.Helper.Query.LinqHelper
  7. {
  8. public static class DynamicLinq
  9. {
  10. /// <summary>
  11. /// 创建参数表达式
  12. /// </summary>
  13. /// <typeparam name="T"></typeparam>
  14. /// <param name="name"></param>
  15. /// <returns></returns>
  16. public static ParameterExpression CreateLambdaParam<T>(string name)
  17. {
  18. return Expression.Parameter(typeof(T), name);
  19. }
  20. /// <summary>
  21. /// 创建linq表达示的body部分
  22. /// </summary>
  23. public static Expression GenerateBody<T>(this ParameterExpression param, Filter filterObj)
  24. {
  25. PropertyInfo property = typeof(T).GetProperty(filterObj.Key);
  26. //组装左边
  27. Expression left = Expression.Property(param, property);
  28. //组装右边
  29. Expression right = null;
  30. if (property.PropertyType == typeof(int))
  31. {
  32. right = Expression.Constant(int.Parse(filterObj.Value));
  33. }
  34. else if (property.PropertyType == typeof(DateTime))
  35. {
  36. right = Expression.Constant(DateTime.Parse(filterObj.Value));
  37. }
  38. else if (property.PropertyType == typeof(string))
  39. {
  40. right = Expression.Constant((filterObj.Value));
  41. }
  42. else if (property.PropertyType == typeof(decimal))
  43. {
  44. right = Expression.Constant(decimal.Parse(filterObj.Value));
  45. }
  46. else if (property.PropertyType == typeof(Guid))
  47. {
  48. right = Expression.Constant(Guid.Parse(filterObj.Value));
  49. }
  50. else if (property.PropertyType == typeof(bool))
  51. {
  52. right = Expression.Constant(filterObj.Value.Equals("1"));
  53. }
  54. else if (property.PropertyType == typeof(Guid?))
  55. {
  56. left = Expression.Property(left, "Value");
  57. right = Expression.Constant(Guid.Parse(filterObj.Value));
  58. }
  59. else
  60. {
  61. throw new Exception("暂不能解析该Key的类型");
  62. }
  63. //c.XXX=="XXX"
  64. Expression filter = Expression.Equal(left, right);
  65. switch (filterObj.Contrast)
  66. {
  67. case "<=":
  68. filter = Expression.LessThanOrEqual(left, right);
  69. break;
  70. case "<":
  71. filter = Expression.LessThan(left, right);
  72. break;
  73. case ">":
  74. filter = Expression.GreaterThan(left, right);
  75. break;
  76. case ">=":
  77. filter = Expression.GreaterThanOrEqual(left, right);
  78. break;
  79. case "!=":
  80. filter = Expression.NotEqual(left, right);
  81. break;
  82. case "like":
  83. filter = Expression.Call(left, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),
  84. Expression.Constant(filterObj.Value));
  85. break;
  86. case "not in":
  87. var listExpression = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组
  88. var method = typeof(List<string>).GetMethod("Contains", new Type[] { typeof(string) }); //Contains语句
  89. filter = Expression.Not(Expression.Call(listExpression, method, left));
  90. break;
  91. case "in":
  92. var lExp = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组
  93. var methodInfo = typeof(List<string>).GetMethod("Contains", new Type[] { typeof(string) }); //Contains语句
  94. filter = Expression.Call(lExp, methodInfo, left);
  95. break;
  96. }
  97. return filter;
  98. }
  99. public static Expression<Func<T, bool>> GenerateTypeBody<T>(this ParameterExpression param, Filter filterObj)
  100. {
  101. return (Expression<Func<T, bool>>)(param.GenerateBody<T>(filterObj));
  102. }
  103. /// <summary>
  104. /// 创建完整的lambda
  105. /// </summary>
  106. public static LambdaExpression GenerateLambda(this ParameterExpression param, Expression body)
  107. {
  108. //c=>c.XXX=="XXX"
  109. return Expression.Lambda(body, param);
  110. }
  111. public static Expression<Func<T, bool>> GenerateTypeLambda<T>(this ParameterExpression param, Expression body)
  112. {
  113. return (Expression<Func<T, bool>>)(param.GenerateLambda(body));
  114. }
  115. public static Expression AndAlso(this Expression expression, Expression expressionRight)
  116. {
  117. return Expression.AndAlso(expression, expressionRight);
  118. }
  119. public static Expression Or(this Expression expression, Expression expressionRight)
  120. {
  121. return Expression.Or(expression, expressionRight);
  122. }
  123. public static Expression And(this Expression expression, Expression expressionRight)
  124. {
  125. return Expression.And(expression, expressionRight);
  126. }
  127. public static IQueryable<T> Where<T>(this IQueryable<T> query, Expression expression)
  128. {
  129. Expression expr = Expression.Call(typeof(Queryable), "Where", new[] { typeof(T) },
  130. Expression.Constant(query), expression);
  131. //生成动态查询
  132. IQueryable<T> result = query.Provider.CreateQuery<T>(expr);
  133. return result;
  134. }
  135. public static IQueryable<T> GenerateFilter<T>(this IQueryable<T> query, IEnumerable<Filter> filters)
  136. {
  137. if (filters != null)
  138. {
  139. // var filters = JsonHelper.Instance.Deserialize<IEnumerable<Filter>>(filterjson);
  140. var param = CreateLambdaParam<T>("c");
  141. //条件为ture
  142. Expression result = Expression.Constant(true);
  143. foreach (var filter in filters)
  144. {
  145. result = result.AndAlso(param.GenerateBody<T>(filter));
  146. }
  147. query = query.Where(param.GenerateTypeLambda<T>(result));
  148. }
  149. return query;
  150. }
  151. }
  152. }