OrderByString.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace Ropin.Inspection.Repository
  9. {
  10. internal static class LinqExtensions
  11. {
  12. private static PropertyInfo GetPropertyInfo(Type objType, string name)
  13. {
  14. var properties = objType.GetProperties();
  15. var matchedProperty = properties.FirstOrDefault(p => p.Name == name);
  16. if (matchedProperty == null)
  17. {
  18. throw new ArgumentException("name");
  19. }
  20. return matchedProperty;
  21. }
  22. private static LambdaExpression GetOrderExpression(Type objType, PropertyInfo pi)
  23. {
  24. var paramExpr = Expression.Parameter(objType);
  25. var propAccess = Expression.PropertyOrField(paramExpr, pi.Name);
  26. var expr = Expression.Lambda(propAccess, paramExpr);
  27. return expr;
  28. }
  29. /// <summary>
  30. /// 多个OrderBy用逗号隔开,属性前面带-号表示反序排序,exp:"name,-createtime"
  31. /// </summary>
  32. /// <typeparam name="T"></typeparam>
  33. /// <param name="query"></param>
  34. /// <param name="name"></param>
  35. /// <returns></returns>
  36. public static IEnumerable<T> OrderByBatch<T>(this IEnumerable<T> query, string name)
  37. {
  38. var index = 0;
  39. var a = name.Split(',');
  40. foreach (var item in a)
  41. {
  42. var m = index++ > 0 ? "ThenBy" : "OrderBy";
  43. if (item.StartsWith("-"))
  44. {
  45. m += "Descending";
  46. name = item.Substring(1);
  47. }
  48. else
  49. {
  50. name = item;
  51. }
  52. name = name.Trim();
  53. var propInfo = GetPropertyInfo(typeof(T), name);
  54. var expr = GetOrderExpression(typeof(T), propInfo);
  55. var method = typeof(Enumerable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2);
  56. var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
  57. query = (IEnumerable<T>)genericMethod.Invoke(null, new object[] { query, expr.Compile() });
  58. }
  59. return query;
  60. }
  61. /// <summary>
  62. /// 多个OrderBy用逗号隔开,属性前面带-号表示反序排序,exp:"name,-createtime"
  63. /// </summary>
  64. /// <typeparam name="T"></typeparam>
  65. /// <param name="query"></param>
  66. /// <param name="name"></param>
  67. /// <returns></returns>
  68. public static IQueryable<T> OrderByBatch<T>(this IQueryable<T> query, string name)
  69. {
  70. var index = 0;
  71. var a = name.Split(',');
  72. foreach (var item in a)
  73. {
  74. var m = index++ > 0 ? "ThenBy" : "OrderBy";
  75. if (item.StartsWith("-"))
  76. {
  77. m += "Descending";
  78. name = item.Substring(1);
  79. }
  80. else
  81. {
  82. name = item;
  83. }
  84. name = name.Trim();
  85. var propInfo = GetPropertyInfo(typeof(T), name);
  86. var expr = GetOrderExpression(typeof(T), propInfo);
  87. var method = typeof(Queryable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2);
  88. var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
  89. query = (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr });
  90. }
  91. return query;
  92. }
  93. /// <summary>
  94. /// 正序排序单个
  95. /// </summary>
  96. /// <typeparam name="T"></typeparam>
  97. /// <param name="query"></param>
  98. /// <param name="name"></param>
  99. /// <returns></returns>
  100. public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string name)
  101. {
  102. var propInfo = GetPropertyInfo(typeof(T), name);
  103. var expr = GetOrderExpression(typeof(T), propInfo);
  104. var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderBy" && m.GetParameters().Length == 2);
  105. var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
  106. return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr });
  107. }
  108. /// <summary>
  109. /// 正序排序单个(非首个)
  110. /// </summary>
  111. /// <typeparam name="T"></typeparam>
  112. /// <param name="query"></param>
  113. /// <param name="name"></param>
  114. /// <returns></returns>
  115. public static IQueryable<T> ThenBy<T>(this IQueryable<T> query, string name)
  116. {
  117. var propInfo = GetPropertyInfo(typeof(T), name);
  118. var expr = GetOrderExpression(typeof(T), propInfo);
  119. var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "ThenBy" && m.GetParameters().Length == 2);
  120. var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
  121. return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr });
  122. }
  123. /// <summary>
  124. /// 反序排序单个
  125. /// </summary>
  126. /// <typeparam name="T"></typeparam>
  127. /// <param name="query"></param>
  128. /// <param name="name"></param>
  129. /// <returns></returns>
  130. public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string name)
  131. {
  132. var propInfo = GetPropertyInfo(typeof(T), name);
  133. var expr = GetOrderExpression(typeof(T), propInfo);
  134. var metMethods = typeof(Queryable).GetMethods();
  135. var method = metMethods.FirstOrDefault(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2);
  136. var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
  137. return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr });
  138. }
  139. /// <summary>
  140. /// 反序排序单个(非首个)
  141. /// </summary>
  142. /// <typeparam name="T"></typeparam>
  143. /// <param name="query"></param>
  144. /// <param name="name"></param>
  145. /// <returns></returns>
  146. public static IQueryable<T> ThenByDescending<T>(this IQueryable<T> query, string name)
  147. {
  148. var propInfo = GetPropertyInfo(typeof(T), name);
  149. var expr = GetOrderExpression(typeof(T), propInfo);
  150. var metMethods = typeof(Queryable).GetMethods();
  151. var method = metMethods.FirstOrDefault(m => m.Name == "ThenByDescending" && m.GetParameters().Length == 2);
  152. var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
  153. return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr });
  154. }
  155. }
  156. }