使用表达式类与LINQ查询

3
我想知道是否有一种方法可以使用Expression类在LINQ查询中进行自定义查询,例如:
Expression<Func<TEntity, bool>> expression = (x) => x.Id = 1

var items = from item in context.TEntity
where expression
select item

我知道可以使用LINQ函数来实现这个功能,因为Where函数接受表达式作为参数,但我真的需要使用LINQ查询来完成。
注意:上面的代码只是一个示例,让您了解我想要做什么,它不是实际工作代码。
注意2:我需要这个在Entity Framework中工作。
2个回答

4

不幸的是,Entity Framework不支持这种类型的表达式投影,因此常见的尝试,如 where expression.Compile().Invoke(item); 将在运行时引发异常。

但是,如果你使用LinqKit库(它使用Expression Visitor),并在实体集上调用.AsExpandable(),则可以动态地调用您的表达式:

Expression<Func<TEntity, bool>> expression = x => x.Id == 1;

var items = from item in context.Set<TEntity>.AsExpandable()
where expression.Invoke(item)
select item;

哎呀,你是正确的。那个Invoke是Linqkit的扩展方法,与AsExpandable一起使用。 - David L
@DavidL,啊,现在明白了。感谢您的更新。 - Kirill Shlenskiy
@KirillShlenskiy 没问题,感谢你提出来! - David L

1
这个在EF Core上有效(我刚测试过)。没有EF6项目可以测试。
Expression<Func<TEntity, bool>> expression = (x) => x.Id = 1

var items = from item in context.TEntity
where expression.Compile()(item);
select item
更新:我刚刚在EF6上制作了一个简单的测试项目,但它无法工作,因为它无法识别表达式调用。

我真的很惊讶EF Core上可以正常工作... 我得检查一下它是在进行本地过滤(据我所知,计划支持)还是实际上转化为SQL,但现在我没有时间做这个。 - Jcl
2
它确实进行本地过滤。因此,他们消除了运行时异常,但是如果想确保查询在数据库端执行,您必须打开日志记录并检查每个查询。 - Ivan Stoev
@IvanStoev 是的,我也这样想...我尝试启用日志记录,但似乎没有一致的方法来实现,并且我没有太多时间进行测试(它们在3个不同版本中更改了3次,我在github问题上找到的最后一个方法在发布的nuget软件包中不起作用)。 - Jcl
@Jcl 非常有趣...可惜它不支持正确的投影。然而,它看起来已经开始为RowNumber使用ExpressionVisitor模式。也许他们会进一步扩展到多种常见表达式类型。 - David L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接