我有两个这样定义的表达式树:
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查询并传递给数据库。
P.S。:我想使用EntityDataModel做一些Query构建器。有n场和m条件。我想为条件定义字段和m表达式的n表达式,然后将它们组合起来。
答案 0 :(得分: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函数中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;
}
}
显然,如果在表达式中引入多个参数,事情就会变得复杂一些。