private static Expression <T> Compose <T>(this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { // build parameter map (from parameters of second to parameters of first) var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); // replace parameters in the second lambda expression with parameters from the first var secondBody = RebindParameterVisitor.ReplaceParameters(map, second.Body); // apply composition of lambda expression bodies to parameters from the first expression return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters)); }
public static Expression <T> Compose <T>( this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }) .ToDictionary(p => p.s, p => p.f); var secondBody = RebindParameterVisitor.ReplaceParameters(map, second.Body); return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters)); }
/// <summary> /// Joins two binary lambda expressions using the 'Or' conditional operator. /// </summary> /// <typeparam name="T"> /// The type of the predicate. /// </typeparam> /// <param name="left"> /// The first <see cref="Expression{TDelegate}" />. /// </param> /// <param name="right"> /// The second <see cref="Expression{TDelegate}" />. /// </param> /// <returns> /// The resulting <see cref="Expression{TDelegate}" /> object that contains the joined /// <see cref="Expression{TDelegate}" /> objects. /// </returns> public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > left, Expression <Func <T, bool> > right) { Expression <Func <T, bool> > all = t => true; if (left == all || right == all) { return(all); } var rightExprBody = new RebindParameterVisitor(right.Parameters[0], left.Parameters[0]).Visit(right.Body); return(Expression.Lambda <Func <T, bool> >(Expression.OrElse(left.Body, rightExprBody ?? throw new InvalidOperationException()), left.Parameters)); }
/// <summary> /// Joins two binary lambda expressions using the 'And' conditional operator. /// </summary> /// <typeparam name="T"> /// The type of the predicate. /// </typeparam> /// <param name="left"> /// The left <see cref="Expression{TDelegate}" />. /// </param> /// <param name="right"> /// The right <see cref="Expression{TDelegate}" />. /// </param> /// <returns> /// The resulting <see cref="Expression{TDelegate}" /> object that contains the joined /// <see cref="Expression{TDelegate}" /> objects. /// </returns> public static Expression <Func <T, bool> > And <T>(this Expression <Func <T, bool> > left, Expression <Func <T, bool> > right) { Expression <Func <T, bool> > all = t => true; if (Lambda.ExpressionsEqual(left, all)) { return(right); } if (Lambda.ExpressionsEqual(right, all)) { return(left); } var rightExprBody = new RebindParameterVisitor(right.Parameters[0], left.Parameters[0]).Visit(right.Body); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left.Body, rightExprBody ?? throw new InvalidOperationException()), left.Parameters)); }
/// <summary> OR </summary> public static Expression <Func <T, bool> > Or <T>( this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { if (expr1 is null) { throw new ArgumentNullException(nameof(expr1)); } if (expr2 is null) { throw new ArgumentNullException(nameof(expr2)); } var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]) .Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >( Expression.OrElse(expr1.Body, expr2Body), expr1.Parameters)); }
/// <summary> AND </summary> public static Expression <Func <T, bool> > And <T>([NotNull] this Expression <Func <T, bool> > expr1, [NotNull] Expression <Func <T, bool> > expr2) { var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(expr1.Body, expr2Body), expr1.Parameters)); }
public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >(Expression.OrElse(expr1.Body, expr2Body), expr1.Parameters)); }
/// <summary> /// 建立And查询条件 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="leftExpression">左表达式</param> /// <param name="rightExpression">右表达式</param> /// <returns>组合后的表达式</returns> public static Expression <Func <T, bool> > And <T>([NotNull] this Expression <Func <T, bool> > leftExpression, [NotNull] Expression <Func <T, bool> > rightExpression) { var expr2Body = new RebindParameterVisitor(rightExpression.Parameters[0], leftExpression.Parameters[0]).Visit(rightExpression.Body); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(leftExpression.Body, expr2Body), leftExpression.Parameters)); }
/// <summary> /// Joins two binary lambda expressions using the 'Or' conditional operator. /// </summary> /// <typeparam name="T"> /// The type of the predicate. /// </typeparam> /// <param name="left"> /// The first <see cref="Expression{TDelegate}" />. /// </param> /// <param name="right"> /// The second <see cref="Expression{TDelegate}" />. /// </param> /// <returns> /// The resulting <see cref="Expression{TDelegate}" /> object that contains the joined /// <see cref="Expression{TDelegate}" /> objects. /// </returns> public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > left, Expression <Func <T, bool> > right) { var leftExprBody = new RebindParameterVisitor(right.Parameters[0], left.Parameters[0]).Visit(right.Body); return(Expression.Lambda <Func <T, bool> >(Expression.OrElse(left.Body, leftExprBody ?? throw new InvalidOperationException()), left.Parameters)); }