1
1

QueryableExtentions.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. using Masuit.Tools.Mapping.Core;
  2. using System;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. namespace Masuit.Tools.Mapping.Extensions
  6. {
  7. /// <summary>
  8. /// IQueryable的扩展
  9. /// </summary>
  10. public static class QueryableExtentions
  11. {
  12. /// <summary>
  13. /// 根据键按升序对序列的元素进行排序。
  14. /// </summary>
  15. /// <typeparam name="TSource">源类型</typeparam>
  16. /// <typeparam name="TTarget">目标类型</typeparam>
  17. /// <param name="query">分类化的序列值</param>
  18. /// <param name="sortedPropertyDestName">目标属性的名称</param>
  19. /// <returns></returns>
  20. public static IOrderedQueryable<TSource> OrderBy<TSource, TTarget>(this IQueryable<TSource> query, string sortedPropertyDestName) where TSource : class where TTarget : class
  21. {
  22. // 没有使用MethodBase.GetCurrentMethod().Name,因为效率不高
  23. return CreateSortedMethodCall<TSource, TTarget, IOrderedQueryable<TSource>>(query, "OrderBy", sortedPropertyDestName);
  24. }
  25. /// <summary>
  26. /// 根据键按降序对序列的元素进行排序。
  27. /// </summary>
  28. /// <typeparam name="TSource">源类型</typeparam>
  29. /// <typeparam name="TTarget">目标类型</typeparam>
  30. /// <param name="query">分类化的序列值</param>
  31. /// <param name="sortedPropertyDestName">目标属性的名称</param>
  32. /// <returns></returns>
  33. public static IOrderedQueryable<TSource> OrderByDescending<TSource, TTarget>(this IQueryable<TSource> query, string sortedPropertyDestName) where TSource : class where TTarget : class
  34. {
  35. return CreateSortedMethodCall<TSource, TTarget, IOrderedQueryable<TSource>>(query, "OrderByDescending", sortedPropertyDestName);
  36. }
  37. /// <summary>
  38. /// 根据键按升序对序列的元素进行排序。
  39. /// </summary>
  40. /// <typeparam name="TSource">源类型</typeparam>
  41. /// <typeparam name="TTarget">目标类型</typeparam>
  42. /// <param name="query">分类化的序列值</param>
  43. /// <param name="sortedPropertyDestName">目标属性的名称</param>
  44. public static IOrderedQueryable<TSource> ThenBy<TSource, TTarget>(this IQueryable<TSource> query, string sortedPropertyDestName) where TSource : class where TTarget : class
  45. {
  46. return CreateSortedMethodCall<TSource, TTarget, IOrderedQueryable<TSource>>(query, "ThenBy", sortedPropertyDestName);
  47. }
  48. /// <summary>
  49. /// 根据键按降序对序列的元素进行排序。
  50. /// </summary>
  51. /// <typeparam name="TSource">源类型</typeparam>
  52. /// <typeparam name="TTarget">目标类型</typeparam>
  53. /// <param name="query">分类化的序列值</param>
  54. /// <param name="sortedPropertyDestName">目标属性的名称</param>
  55. public static IOrderedQueryable<TSource> ThenByDescending<TSource, TTarget>(this IQueryable<TSource> query, string sortedPropertyDestName) where TSource : class where TTarget : class
  56. {
  57. return CreateSortedMethodCall<TSource, TTarget, IOrderedQueryable<TSource>>(query, "ThenByDescending", sortedPropertyDestName);
  58. }
  59. /// <summary>
  60. /// 通过合并目标对象将序列的每个元素投影到新表单中。
  61. /// </summary>
  62. /// <typeparam name="TSource">源类型.</typeparam>
  63. /// <typeparam name="TTarget">目标类型.</typeparam>
  64. /// <param name="query">分类化的序列值</param>
  65. public static IQueryable<TTarget> Select<TSource, TTarget>(this IQueryable<TSource> query) where TSource : class where TTarget : class
  66. {
  67. return GetSelect<TSource, TTarget>(query, null);
  68. }
  69. /// <summary>
  70. /// 通过合并目标对象将序列的每个元素投影到新表单中。
  71. /// </summary>
  72. /// <typeparam name="TSource">源类型.</typeparam>
  73. /// <typeparam name="TTarget">目标类型.</typeparam>
  74. /// <param name="query">分类化的序列值</param>
  75. /// <param name="mapperName">mapper别名</param>
  76. /// <returns></returns>
  77. public static IQueryable<TTarget> Select<TSource, TTarget>(this IQueryable<TSource> query, string mapperName) where TSource : class where TTarget : class
  78. {
  79. return GetSelect<TSource, TTarget>(query, mapperName);
  80. }
  81. /// <summary>
  82. /// 根据谓词过滤一系列值。
  83. /// </summary>
  84. /// <typeparam name="TSource">源类型</typeparam>
  85. /// <typeparam name="TTarget">目标类型</typeparam>
  86. /// <param name="query">分类化的序列值</param>
  87. /// <param name="predicate">用于根据条件测试每个元素的功能。</param>
  88. /// <returns></returns>
  89. public static IQueryable<TTarget> Where<TSource, TTarget>(this IQueryable<TTarget> query, Expression<Func<TSource, bool>> predicate)
  90. {
  91. return Queryable.Where(query, predicate.ConvertTo<TSource, TTarget>());
  92. }
  93. private static TQueryable CreateSortedMethodCall<TSource, TTarget, TQueryable>(IQueryable<TSource> query, string methodName, string sortedPropertySourceName) where TSource : class where TTarget : class where TQueryable : class, IQueryable<TSource>
  94. {
  95. MapperConfiguration<TSource, TTarget> mapper = ExpressionMapper.GetMapper<TSource, TTarget>();
  96. var prop = mapper.GetLambdaDest(sortedPropertySourceName);
  97. var lambda = mapper.GetSortedExpression(sortedPropertySourceName);
  98. MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[]
  99. {
  100. typeof(TSource),
  101. prop.Type
  102. }, query.Expression, Expression.Quote(lambda));
  103. return query.Provider.CreateQuery<TSource>(resultExp) as TQueryable;
  104. }
  105. private static IQueryable<TTarget> GetSelect<TSource, TTarget>(IQueryable<TSource> query, string mapperName) where TSource : class where TTarget : class
  106. {
  107. // 不需要mapper
  108. if (typeof(TSource) == typeof(TTarget))
  109. {
  110. return (IQueryable<TTarget>)query;
  111. }
  112. return query.Select(ExpressionMapper.GetMapper<TSource, TTarget>(mapperName).GetLambdaExpression());
  113. }
  114. }
  115. }