将表达式树作为参数传递给实体数据模型中的另一个表达式树
本文关键字:表达式 数据模型 另一个 实体 参数传递 | 更新日期: 2023-09-27 18:32:17
我有两个表达式树,定义如下:
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));
但是我不能使用编译或调用方法,因为我使用的是EntityDataModel。当我将"表达式"传递给 Where 方法时,它会转换为 SQL 查询并传递给数据库。
PS:我想使用EntityDataModel做某种查询构建器。有 n 场和 m 条件。我想为字段定义 n 个表达式,为条件定义 m 表达式,然后将它们组合在一起。
选项 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;
}
}
显然,如果您在表达式中引入多个参数,事情会变得更加复杂。