什么是EF重写规则?

Bre*_*ias 10 c# sql linq code-generation entity-framework

当使用DBContext编写LINQ查询语法表达式时,C#编译器会使用其18个转换/术语重写规则列表将其查询语法转换为点/扩展语法.然后,当执行查询时,EF应用其自己的内部重写规则来生成SQL表达式.

就像我上面链接的文章一样,我想要列出EF正在应用的重写规则.我在哪里可以找到它?如果我知道EF重写规则,我可以预测SQL EF将为给定查询生成什么,而不必等到运行时"看到"生成的SQL.

例如,请考虑以下两个查询:

var result = from c in context.Customers
             from a in c.Accounts
             where c.ID > 2
             select a;

var result = from c in context.Customers
             where c.ID > 2
             from a in c.Accounts
             select a;
Run Code Online (Sandbox Code Playgroud)

当C#编译器完成自己的重写规则时,上述查询将转换为带有以下各种格式的点表示法:

SelectMany(...).Where(...).Select(...); //for the first query

Where(...).SelectMany(...); // for the second query
Run Code Online (Sandbox Code Playgroud)

在这些转换之后,EF开始应用自己的重写规则.但是EF对于上述两个查询都有一个标准化形式.换句话说,两个查询都会产生相同的结果; 任一查询都会生成以下SQL语句:

SELECT 
    [Extent1].[ID] AS [ID], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Stat_ID] AS [Stat_ID]
    FROM  [dbo].[Customers] AS [Extent1]
    INNER JOIN [dbo].[Accounts] AS [Extent2] ON [Extent1].[ID] = [Extent2].[Customer_ID]
    WHERE [Extent2].[ID] > 2
Run Code Online (Sandbox Code Playgroud)

在不知道EF重写规则的情况下,我无法预测到这一点.我只需要执行和调试代码来进行观察.

那么,我在哪里可以找到EF正在应用的重写规则列表?

我也很好奇EF应用规则的实施策略.这是一篇讨论几种重写规则策略的文章.也许我可以通过研究EF源代码来发现这一点,但我正在做的,但我还没有.

Ale*_*lex 1

遗憾的是,将 linq 表达式转换为 SQL 非常复杂,并且可能不容易分解为一组简单的离散规则。

例如,诸如 linqGroupBy和 之类的东西Join不倾向于一对一映射到同名的 SQL 关键字,因为它们在 linq 中的行为与在 SQL 中的行为略有不同(linqGroupBy返回组中的所有项目,而不仅仅是聚合,而 linqJoin更像是 SQL Server CROSS APPLY)。实际的转换很大程度上取决于查询末尾选择的内容,这意味着您通常必须处理整个表达式,而不是 linq 方法到 SQL 关键字的简单映射。

非常值得阅读 Matt Warren 关于构建 linq 提供程序的文章http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx。它可能不完全是 EF 正在做的事情,但让您了解将 linq 表达式转换为 sql 涉及哪些步骤以及所涉及的复杂性。