0

我有两个这样定义的表达式树:

Expression<Func<string, bool>> BoolExpression { get; }

Expression<Func<Customer, string>> PropertyExpression { get; }

我需要创建一个新的表达式树,结果相当于:

Customer c = null;
var expression = e1(e2(c));

我可以用 Compile()、Invoke() 来做到这一点:

Customers c = null;
var e3 = e1.Compile().Invoke(e2.Compile().Invoke(c));

但我不能使用 Compile 或 Invoke 方法,因为我使用的是 EntityDataModel。当我将“表达式”传递给 Where 方法时,它会转换为 SQL 查询并传递给数据库。

PS:我想使用 EntityDataModel 做某种查询生成器。有 n 个域和 m 个条件。我想为字段定义 n 表达式,为条件定义 m 表达式,然后将它们组合起来。

4

1 回答 1

0

选项1

首先尝试一下 - 我刚刚使用 LINQ-to-SQL 进行了尝试,它可以工作,所以它应该可以在 EF 中工作。这不是你所拥有的一百万英里,只是说调用 e1 与调用 e2 的结果:

var e3 = Expression.Lambda<Func<Customer, bool>>(Expression.Invoke(e1, Expression.Invoke(e2, e2.Parameters)), e2.Parameters);

选项 2

我原以为您需要遍历表达式树并替换 BoolExpression func 中 String 参数的用法,如下所示:

// replace parameter use anywhere in e1.Body with e2.Body
var remover = new ParameterReplaceVisitor(e2.Body);
var bb = remover.Visit(e1.Body);

// create a new lambda with our amended body but still with e2 parameters i.e. the Customer
var e3 = Expression.Lambda<Func<Customer, bool>>(bb, e2.Parameters);

public class ParameterReplaceVisitor : ExpressionVisitor
{
    Expression _replace;

    public ParameterReplaceVisitor(Expression replace)
    {
        _replace = replace;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        // when we encounter a parameter replace it
        return _replace;
    }
}

显然,如果您在表达式中引入多个参数,事情会变得更加复杂。

于 2012-04-25T23:52:22.517 回答