简体   繁体   English

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

[英]Create an expression tree that calls an expression tree

I have a property on a class 我在一堂课上有财产

Expression<Func<Product, int>> predicate;

that will be assigned to different expressions throughout the application. 将在整个应用程序中分配给不同的表达式。

In a method called GetProducts I would like to retrieve Products from the DB using Entity Framework, using this predicate. 在一个名为GetProducts的方法中,我想使用此谓词使用Entity Framework从数据库中检索产品。 I will then have a variable called myInt that I would like to use as the int parameter, that will then be assigned a value. 然后,我将有一个名为myInt的变量,我想将其用作int参数,然后将为其分配一个值。

So I tried 所以我尝试了

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

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

It looks like I need to do some expression tree manipulation, to create a new expression tree, with myInt baked in it. 看来我需要进行一些表达式树操作,以创建一个新的表达式树,并在其中烘焙myInt How can I do this? 我怎样才能做到这一点?

Thank you for your help. 谢谢您的帮助。

OK, got it. 好的,我知道了。

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);

The key is Expression.Invoke that can invoke the predicate, using supplied parameters. 关键是Expression.Invoke ,可以使用提供的参数来调用谓词。

EDIT - After trying it, this only works with linq2sql - with Entity Framework it can't translate InvocationExpression to SQL. 编辑-尝试后,这仅适用于linq2sql-对于Entity Framework,它无法将InvocationExpression转换为SQL。 Instead, I used LinqKit , as follows: 相反,我使用LinqKit ,如下所示:

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

You defined predicate as a Type but you are using it as a method. 您将predicate定义为Type但是您将其用作方法。

You can define a predicate in the following way: 您可以通过以下方式定义谓词:

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

You can also use lambda expressions: 您还可以使用lambda表达式:

product => product.SomeValue > 5

Edit: 编辑:

Expression<Func<Product, int>> predicate = (product,val) => product.SomeValue > val;
var filtered = dbContext.Products.Where(predicate);
  • Avoid using types when naming a parameters (ie don't name an integer MyInt ) 避免在命名参数时使用类型(即,不要将整数命名为MyInt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM