c# - 为什么必须将变量值建模为对表达式树中闭包的成员访问?

标签 c# entity-framework linq lambda linq-expressions

当我在我们的应用程序中将表达式编写为 lambda 表达式时,我通常可以使用以下结构1:

dbContext.Contents<MyEntity>()

(dbContext 属于自定义类。) Linq1Entities/Entity Framework 以某种方式理解这意味着我正在从匹配 MyEntity 的表中SELECTing 项目。

现在,我正在通过 System.Linq.Expressions 类构造一个表达式。 我试图像这样复制上面的片段:

Expression.Call(Expression.Constant(dbContext), contentsMethod)

contentsMethod 之前已经通过反射的方式初始化为合适的MethodInfo

不幸的是,这不起作用。 Entity Framework 提示它无法将 dbContext 对象转换为 SQL。

我构建了一个我想要的类似表达式作为 lambda 表达式,并在调试器中查看了生成的表达式树。 有趣的是,常量dbContext 被建模为似乎是闭包对象的成员访问

这是为什么?为什么局部变量 dbContext 由成员访问表达式中的闭包表示,为什么它不能作为常量值工作?在我的案例中,dbContext 是封闭方法的参数是否重要?

我的问题不是如何解决问题。 我已经这样做了,将上面显示的片段作为一个额外的 lambda 表达式引入,其主体与我手动构建的表达式相关联。


1:该片段如何使用的示例是以下表达式:

dbContext.Contents<MyEntity1>().Where(e1 => dbContext.Contents<MyEntity2>().Any(e2 => e1.Name == e2.Key))

最佳答案

dbContext 被建模为对闭包对象的访问,因为定义它的 lambda 正在关闭该变量。它没有使用常量值,而是关闭了另一个值,所以这就是它在 Expression 中表示的内容。如果它做了任何其他事情,它就不能正确地表示 lambda。

当 EF 说它不能将 Expression 转换为 SQL 时,它只是说代码的作者没有预料到给定的表达式,也没有创建该模式的映射到 SQL;他们根本没有预料到人们会这样做(或者不知道如何将其映射到 SQL,或者不能,或者没有时间添加该功能,无论如何)。

关于c# - 为什么必须将变量值建模为对表达式树中闭包的成员访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44025703/

相关文章:

c# - linq where 子句和计数导致空异常

c# - Lambda 表达式帮助

c# - 比较相同用户定义类型的两个列表

c# - 如何在 .NET Core 控制台应用程序中设置 DI 容器?

c# - 在javascript函数中使用asp.net的图像组件

c# - asp.Net 如何将数据保存到 Controller 中的联结表

c# - 显式变量声明

c# - FileNet P8 工作场所 token 问题

c# - CAML 查询仅检索来自 SharePoint 2007 的已发布页面?

c# - 使用字符串操作和正则表达式的 LINQ 查询结果