创建调用表达式树的表达式树

本文关键字:表达式 调用 创建 | 更新日期: 2023-09-27 18:35:06

我在类上有一个属性

Expression<Func<Product, int>> predicate;

这将分配给整个应用程序的不同表达式。

在一个名为 GetProducts 的方法中,我想使用此谓词使用实体框架从数据库中检索产品。然后,我将有一个名为 myInt 的变量,我想将其用作 int 参数,然后为该变量分配一个值。

所以我尝试了

dbContext.Products.Where(p => predicate(p, myInt))

但我得到了Non-invocable member 'predicate' cannot be used like a method.错误。

看起来我需要做一些表达式树操作,创建一个新的表达式树,其中包含myInt。我该怎么做?

谢谢你的帮助。

创建调用表达式树的表达式树

您将predicate定义为Type,但将其用作方法。

可以通过以下方式定义谓词:

private bool predicate(Product product, int myInt)
{
    //put your logic here
    return true;
}

您还可以使用 lambda 表达式:

product => product.SomeValue > 5

编辑:

Expression<Func<Product, int>> predicate = (product,val) => product.SomeValue > val;
var filtered = dbContext.Products.Where(predicate);
  • 命名参数时避免使用类型(即不要命名整数MyInt

好的,知道了。

ParameterExpression prm = Expression.Parameter(typeof(Product));
InvocationExpression inv = Expression.Invoke(predicate, prm, Expression.Constant(myInt));
var lambda = (Expression<Func<Product,bool>>) Expression.Lambda(inv, prm);
dbContext.Products.Where(lambda);

键是可以使用提供的参数调用谓词的Expression.Invoke

编辑 - 尝试后,这仅适用于linq2sql - 使用实体框架,它无法将InvocationExpression转换为SQL。相反,我使用了 LinqKit,如下所示:

dbContext.Products.AsExpandable().Where(p => predicate.Invoke(p, myInt))