LinqExtension.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. namespace Masuit.Tools.Linq
  6. {
  7. /// <summary>
  8. /// LINQ扩展方法
  9. /// </summary>
  10. public static class LinqExtension
  11. {
  12. /// <summary>
  13. /// 与连接
  14. /// </summary>
  15. /// <typeparam name="T">类型</typeparam>
  16. /// <param name="left">左条件</param>
  17. /// <param name="right">右条件</param>
  18. /// <returns>新表达式</returns>
  19. public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
  20. {
  21. return CombineLambdas(left, right, ExpressionType.AndAlso);
  22. }
  23. /// <summary>
  24. /// 或连接
  25. /// </summary>
  26. /// <typeparam name="T">类型</typeparam>
  27. /// <param name="left">左条件</param>
  28. /// <param name="right">右条件</param>
  29. /// <returns>新表达式</returns>
  30. public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
  31. {
  32. return CombineLambdas(left, right, ExpressionType.OrElse);
  33. }
  34. private static Expression<Func<T, bool>> CombineLambdas<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right, ExpressionType expressionType)
  35. {
  36. var visitor = new SubstituteParameterVisitor
  37. {
  38. Sub =
  39. {
  40. [right.Parameters[0]] = left.Parameters[0]
  41. }
  42. };
  43. Expression body = Expression.MakeBinary(expressionType, left.Body, visitor.Visit(right.Body));
  44. return Expression.Lambda<Func<T, bool>>(body, left.Parameters[0]);
  45. }
  46. private static bool IsExpressionBodyConstant<T>(Expression<Func<T, bool>> left)
  47. {
  48. return left.Body.NodeType == ExpressionType.Constant;
  49. }
  50. /// <summary>
  51. /// 取最大值
  52. /// </summary>
  53. /// <typeparam name="TSource"></typeparam>
  54. /// <typeparam name="TResult"></typeparam>
  55. /// <param name="source"></param>
  56. /// <param name="selector"></param>
  57. /// <returns></returns>
  58. public static TResult MaxOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) => source.Select(selector).OrderByDescending(_ => _).FirstOrDefault();
  59. /// <summary>
  60. /// 取最大值
  61. /// </summary>
  62. /// <typeparam name="TSource"></typeparam>
  63. /// <param name="source"></param>
  64. /// <returns></returns>
  65. public static TSource MaxOrDefault<TSource>(this IQueryable<TSource> source) => source.OrderByDescending(_ => _).FirstOrDefault();
  66. /// <summary>
  67. /// 取最大值
  68. /// </summary>
  69. /// <typeparam name="TSource"></typeparam>
  70. /// <typeparam name="TResult"></typeparam>
  71. /// <param name="source"></param>
  72. /// <param name="selector"></param>
  73. /// <returns></returns>
  74. public static TResult MaxOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) => source.Select(selector).OrderByDescending(_ => _).FirstOrDefault();
  75. /// <summary>
  76. /// 取最大值
  77. /// </summary>
  78. /// <typeparam name="TSource"></typeparam>
  79. /// <param name="source"></param>
  80. /// <returns></returns>
  81. public static TSource MaxOrDefault<TSource>(this IEnumerable<TSource> source) => source.OrderByDescending(_ => _).FirstOrDefault();
  82. /// <summary>
  83. /// 取最小值
  84. /// </summary>
  85. /// <typeparam name="TSource"></typeparam>
  86. /// <typeparam name="TResult"></typeparam>
  87. /// <param name="source"></param>
  88. /// <param name="selector"></param>
  89. /// <returns></returns>
  90. public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) => source.Select(selector).OrderBy(_ => _).FirstOrDefault();
  91. /// <summary>
  92. /// 取最小值
  93. /// </summary>
  94. /// <typeparam name="TSource"></typeparam>
  95. /// <param name="source"></param>
  96. /// <returns></returns>
  97. public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source) => source.OrderBy(_ => _).FirstOrDefault();
  98. /// <summary>
  99. /// 取最小值
  100. /// </summary>
  101. /// <typeparam name="TSource"></typeparam>
  102. /// <typeparam name="TResult"></typeparam>
  103. /// <param name="source"></param>
  104. /// <param name="selector"></param>
  105. /// <returns></returns>
  106. public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) => source.Select(selector).OrderBy(_ => _).FirstOrDefault();
  107. /// <summary>
  108. /// 取最小值
  109. /// </summary>
  110. /// <typeparam name="TSource"></typeparam>
  111. /// <param name="source"></param>
  112. /// <returns></returns>
  113. public static TSource MinOrDefault<TSource>(this IEnumerable<TSource> source) => source.OrderBy(_ => _).FirstOrDefault();
  114. }
  115. internal class SubstituteParameterVisitor : ExpressionVisitor
  116. {
  117. public Dictionary<Expression, Expression> Sub = new Dictionary<Expression, Expression>();
  118. protected override Expression VisitParameter(ParameterExpression node)
  119. {
  120. return Sub.TryGetValue(node, out var newValue) ? newValue : node;
  121. }
  122. }
  123. }