Combining two expressions (Expression>)

前端 未结 7 1530
无人共我
无人共我 2020-11-22 01:09

I have two expressions of type Expression> and I want to take to OR, AND or NOT of these and get a new expression of the same type

7条回答
  •  伪装坚强ぢ
    2020-11-22 01:46

    You can use Expression.AndAlso / OrElse to combine logical expressions, but you have to make sure the ParameterExpressions are the same.

    I was having trouble with EF and the PredicateBuilder so I made my own without resorting to Invoke, that I could use like this:

    var filterC = filterA.And(filterb);
    

    Source code for my PredicateBuilder:

    public static class PredicateBuilder {
    
        public static Expression> And(this Expression> a, Expression> b) {    
    
            ParameterExpression p = a.Parameters[0];
    
            SubstExpressionVisitor visitor = new SubstExpressionVisitor();
            visitor.subst[b.Parameters[0]] = p;
    
            Expression body = Expression.AndAlso(a.Body, visitor.Visit(b.Body));
            return Expression.Lambda>(body, p);
        }
    
        public static Expression> Or(this Expression> a, Expression> b) {    
    
            ParameterExpression p = a.Parameters[0];
    
            SubstExpressionVisitor visitor = new SubstExpressionVisitor();
            visitor.subst[b.Parameters[0]] = p;
    
            Expression body = Expression.OrElse(a.Body, visitor.Visit(b.Body));
            return Expression.Lambda>(body, p);
        }   
    }
    

    And the utility class to substitute the parameters in a lambda:

    internal class SubstExpressionVisitor : System.Linq.Expressions.ExpressionVisitor {
            public Dictionary subst = new Dictionary();
    
            protected override Expression VisitParameter(ParameterExpression node) {
                Expression newValue;
                if (subst.TryGetValue(node, out newValue)) {
                    return newValue;
                }
                return node;
            }
        }
    

提交回复
热议问题