LinqExtension.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. namespace Masuit.Tools.Linq
  5. {
  6. /// <summary>
  7. /// LINQ扩展方法
  8. /// </summary>
  9. public static class LinqExtension
  10. {
  11. /// <summary>
  12. /// 与连接
  13. /// </summary>
  14. /// <typeparam name="T">类型</typeparam>
  15. /// <param name="left">左条件</param>
  16. /// <param name="right">右条件</param>
  17. /// <returns>新表达式</returns>
  18. public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
  19. {
  20. return CombineLambdas(left, right, ExpressionType.AndAlso);
  21. }
  22. /// <summary>
  23. /// 或连接
  24. /// </summary>
  25. /// <typeparam name="T">类型</typeparam>
  26. /// <param name="left">左条件</param>
  27. /// <param name="right">右条件</param>
  28. /// <returns>新表达式</returns>
  29. public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
  30. {
  31. return CombineLambdas(left, right, ExpressionType.OrElse);
  32. }
  33. private static Expression<Func<T, bool>> CombineLambdas<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right, ExpressionType expressionType)
  34. {
  35. var visitor = new SubstituteParameterVisitor
  36. {
  37. Sub =
  38. {
  39. [right.Parameters[0]] = left.Parameters[0]
  40. }
  41. };
  42. Expression body = Expression.MakeBinary(expressionType, left.Body, visitor.Visit(right.Body));
  43. return Expression.Lambda<Func<T, bool>>(body, left.Parameters[0]);
  44. }
  45. private static bool IsExpressionBodyConstant<T>(Expression<Func<T, bool>> left)
  46. {
  47. return left.Body.NodeType == ExpressionType.Constant;
  48. }
  49. internal class SubstituteParameterVisitor : ExpressionVisitor
  50. {
  51. public Dictionary<Expression, Expression> Sub = new Dictionary<Expression, Expression>();
  52. protected override Expression VisitParameter(ParameterExpression node)
  53. {
  54. return Sub.TryGetValue(node, out var newValue) ? newValue : node;
  55. }
  56. }
  57. }
  58. }