DynamicLinq.cs 6.1 KB

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