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

时间:2013-10-13 15:34:20

标签: c# entity-framework

我在课堂上有一个属性

Expression<Func<Product, int>> predicate;

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

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

所以我试过

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

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

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

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

好的,明白了。

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 - 使用Entity Framework它无法将InvocationExpression转换为SQL。相反,我使用了LinqKit,如下所示:

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

答案 1 :(得分:1)

您将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