using System; using System.Linq; using System.Linq.Expressions; namespace Hncore.Infrastructure.EntitiesExtension { /// /// Extension methods for add And and Or with parameters rebinder /// public static class ExpressionBuilder { /// /// Compose two expression and merge all in a new expression /// /// Type of params in expression /// Expression instance /// Expression to merge /// Function to merge /// New merged expressions public static Expression Compose(this Expression first, Expression second, Func 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 = ParameterRebinder.ReplaceParameters(map, second.Body); // apply composition of lambda expression bodies to parameters from the first expression return Expression.Lambda(merge(first.Body, secondBody), first.Parameters); } /// /// And operator /// /// Type of params in expression /// Right Expression in AND operation /// Left Expression in And operation /// New AND expression public static Expression> And(this Expression> first, Expression> second) { return first.Compose(second, Expression.AndAlso); } /// /// Or operator /// /// Type of param in expression /// Right expression in OR operation /// Left expression in OR operation /// New Or expressions public static Expression> Or(this Expression> first, Expression> second) { return first.Compose(second, Expression.Or); } } }