public static Expression <Func <T, bool> > And <T>(Expression <Func <T, bool> > exp, Expression <Func <T, bool> > newExp = null) { if (exp == null && newExp == null) { return(null); } if (exp == null) { return(newExp); } if (newExp == null) { return(exp); } // get the visitor var visitor = new ParameterUpdateVisitor(newExp.Parameters.First(), exp.Parameters.First()); // replace the parameter in the expression just created newExp = visitor.Visit(newExp) as Expression <Func <T, bool> >; // now you can and together the two expressions var binExp = Expression.And(exp.Body, newExp.Body); // and return a new lambda, that will do what you want. NOTE that the binExp has reference only to te newExp.Parameters[0] (there is only 1) parameter, and no other return(Expression.Lambda <Func <T, bool> >(binExp, newExp.Parameters)); }
public static Expression <Func <T, bool> > UpdateParameter <T>(Expression <Func <T, bool> > expr, ParameterExpression newParameter) { var visitor = new ParameterUpdateVisitor(expr.Parameters[0], newParameter); var body = visitor.Visit(expr.Body); return(Expression.Lambda <Func <T, bool> >(body, newParameter)); }
public static Expression <Func <T, bool> > And <T>(this Expression <Func <T, bool> > exp, Expression <Func <T, bool> > newExp) { ParameterUpdateVisitor visitor = new ParameterUpdateVisitor(newExp.Parameters.First(), exp.Parameters.First()); newExp = visitor.Visit(newExp) as Expression <Func <T, bool> >; BinaryExpression binExp = Expression.And(exp.Body, newExp.Body); return(Expression.Lambda <Func <T, bool> >(binExp, newExp.Parameters)); }
public static Expression <Func <T, bool> > OrElse <T>(this Expression <Func <T, bool> > firstExpression, Expression <Func <T, bool> > secondExpression) { var visitor = new ParameterUpdateVisitor(secondExpression.Parameters.First(), firstExpression.Parameters.First()); secondExpression = visitor.Visit(secondExpression) as Expression <Func <T, bool> >; var binExp = Expression.OrElse(firstExpression.Body, secondExpression.Body); return(Expression.Lambda <Func <T, bool> >(binExp, secondExpression.Parameters)); }
public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > expression, Expression <Func <T, bool> > newExpression) { if (expression == null) { return(newExpression); } var visitor = new ParameterUpdateVisitor(newExpression.Parameters.First(), expression.Parameters.First()); newExpression = visitor.Visit(newExpression) as Expression <Func <T, bool> >; var binaryExppression = Expression.Or(expression.Body, newExpression.Body); return(Expression.Lambda <Func <T, bool> >(binaryExppression, newExpression.Parameters)); }
public static LambdaExpression Or(this LambdaExpression exp, LambdaExpression newExp) { // get the visitor var visitor = new ParameterUpdateVisitor(newExp.Parameters.First(), exp.Parameters.First()); // replace the parameter in the expression just created newExp = visitor.Visit(newExp) as LambdaExpression; // now you can or together the two expressions var binExp = Expression.Or(exp.Body, newExp.Body); // and return a new lambda, that will do what you want. NOTE that the binExp has reference only to te newExp.Parameters[0] (there is only 1) parameter, and no other return(Expression.Lambda(binExp, newExp.Parameters)); }
private static LambdaExpression Combine(this LambdaExpression left, LambdaExpression right, Func <Expression, Expression, Expression> operationAction) { if (left.Parameters.Count > 1 || right.Parameters.Count > 1) { throw new NotSupportedException("Not supported that the expression contains more than one parameters"); } var leftParamFirst = left.Parameters.First(); var rightParamFirst = right.Parameters.First(); if (leftParamFirst.Type != rightParamFirst.Type) { throw new NotSupportedException("Not supported that the expressions contains different type of two parameters"); } var visitor = new ParameterUpdateVisitor(rightParamFirst, leftParamFirst); var newRightBody = visitor.Visit(right.Body); var lambdaBody = operationAction(left.Body, newRightBody); var lambda = Expression.Lambda(lambdaBody, leftParamFirst); return(lambda); }
private Expression <Func <T, bool> > AddGlobalTableFilters(Expression <Func <T, bool> > exp) { //Checks if the expression has queries over the Id field, and modifies them by adding the table prefix to the values. var idModifierVisitor = new ModifyIdVisitor(); exp = idModifierVisitor.Visit(exp) as Expression <Func <T, bool> >; //Creates a new expression that restrict the query to only run over the entities that belong to this table Expression <Func <T, bool> > newExp = a => a.Id.CompareTo(tablePrefix) >= 0 && a.Id.CompareTo(tablePrefixUpperBound) < 0; //Updates the new expression to match the parameter of the original expression, so that they can be added together later. var visitor = new ParameterUpdateVisitor(newExp.Parameters.First(), exp.Parameters.First()); newExp = visitor.Visit(newExp) as Expression <Func <T, bool> >; //Logical AND between the new expression and the old expression. var binExp = Expression.And(newExp.Body, exp.Body); //Returns the composit expression. return(Expression.Lambda <Func <T, bool> >(binExp, newExp.Parameters)); }
/// <summary> /// Replaces the old Parameter in the expression with the new parameter /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expression"></param> /// <param name="oldParameter"></param> /// <param name="newParameter"></param> /// <returns></returns> public static Expression <T> ReplaceParameter <T>(this Expression <T> expression, ParameterExpression oldParameter, ParameterExpression newParameter) { var visitor = new ParameterUpdateVisitor(expression.Parameters.First(), newParameter); return(visitor.Visit(expression) as Expression <T>); }
private static Expression GetBody <TParam, TResult>(Expression <Func <TParam, TResult> > exp, ParameterExpression param) { var visitor = new ParameterUpdateVisitor(exp.Parameters[0], param); return(visitor.Visit(exp.Body)); }