EntityFramework 和表达式翻译

EntityFramework and Expressions translation

我有一个实体 class Foo 我做了部分包含以下代码

private readonly static Expression<Func<Foo, int>> MyKeyExpression = (x) => x.Key;

public int MyKey
{
   get { return MyKeyExpression.Compile()(this); }
}

上面的工作原理是我可以在 EntityFrameworks linq 查询中使用 MyKey

为什么下面的方法不起作用?

private readonly static Expression<Func<Foo, int>> MyKeyExpression = (x) => x.Key;

// Set in the constructor with
// _myKeyDelegate = MyKeyExpression.Compile();
private readonly Func<Foo,int> _myKeyDelegate;

public int MyKey
{
   get { return _myKeyDelegate(this); }
}

我理解委托和表达式之间的区别(或者我可能不理解?)但是很困惑 EntityFramework 如何能够以不同的方式解释 属性,因为 MyKeyExpression.Compile() returns 就是那个随后被调用并返回一个 int 的委托。也许是我对编译器实际如何处理 C# 属性缺乏了解?

第一个示例有效但第二个示例抛出无法将其转换为 SQL 的异常的用法示例。:

dbContext.Foo.Delete(x => x.MyKey == 5)

我会说你没有完全理解委托和表达式之间的区别。

Delegate 是对编译成 IL 的代码的引用。您唯一可以使用它的是在 .net CLR 中执行它。

表达式对象是一个表示为树的表达式,(你可以想到AST)。您可以将其编译为 IL(编译方法),也可以检查它并为其他执行环境生成代码,例如 SQL(这就是 EF 所做的)。

C#编译器编译代码时,首先构建语法树,然后编译。基本上表达式是第一部分的结果,没有第二部分,所以你可以使用 SQL 翻译器将它编译成 SQL。或者您可以自己编写并将其翻译成任何其他内容。

你说的很奇怪... EF 忽略映射 属性 (MyKey) 的 getter 和 setter 的内容。

应该使用基于 MyKey 的 WHERE 子句生成查询,而不管 getter 做什么。

您是如何映射 MyKey 属性 的?缺少 setter,因此 EF 不会在数据库 table 上生成字段,也不会自动映射它。