0

我需要动态构建 Expression> 作为 Expression> 对象的结合,例如

Expression<Predicate<string>> expression1 = c => c.Contains("aaa");
Expression<Predicate<string>> expression2 = c => c.Contains("bbb");

如何将这些表达式与 AND 运算符组合以获得另一个

Expression<Predicate<string>>

目的?

谢谢!

4

3 回答 3

1
var par = Expression.Parameter(typeof(string));
Expression<Predicate<string>> expression3 = 
    Expression.Lambda<Predicate<string>>(
        Expression.AndAlso(
            Expression.Invoke(expression1, par), 
            Expression.Invoke(expression2, par)), 
        par);

Predicate<string> method1 = expression3.Compile();
Console.WriteLine(method1("aaa"));
Console.WriteLine(method1("bbb"));
Console.WriteLine(method1("aaabbb"));

我们必须创造一个新的表达方式。par是参数。然后我们使用Expression.Invoke调用“旧”表达式(并par作为它们的参数传递)。然后我们用Expression.AndAlso&&表达。最后我们Expression.Lambda<Predicate<string>>用来创建最终的表达式(最后一个参数,par是lambda表达式的参数名)

请注意(常见错误),Expression.And&,while Expression.AndAlsois &&(相同的Expression.Or*

于 2013-08-07T18:27:44.080 回答
1

你基本上会做使用 所做的事情PredicateBuilder,但Predicate不是Func<T, bool>使用它:

public static Expression<Predicate<string>> And(this Expression<Predicate<string>> expr1,
                                                Expression<Predicate<string>> expr2)
{
    var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
    return Expression.Lambda<Predicate<string>>
            (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}

如果您不介意使用Func<string, bool>而不是Predicate,那么您可以直接使用PredicateBuilder

于 2013-08-07T18:28:03.813 回答
0
Expression<Predicate<string>> expression1 = c => c.Contains("aaa") && c.Contains("bbb");

以上将起作用,并且应该始终是可能的。但是,如果您出于某种原因尝试一般地组合这些谓词,请尝试以下操作:

Expression<Predicate<string>> expression1 = c => c.Contains("aaa");
Expression<Predicate<string>> expression2 = c => c.Contains("bbb");
Expression<Predicate<string>> expression3 = Expression.AndAlso(expression1.body , expression2.body); 

此外,这里是它的文档:http: //msdn.microsoft.com/en-us/library/bb353520.aspx 您会发现 Expression 的其他类似有用的成员

于 2013-08-07T18:23:55.803 回答