QueryableExtentions.cs 6.1 KB

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