sql - 为什么 Entity Framework 会生成此 SQL?

标签 sql linq-to-entities

我有这个 LINQ 语句,

var carriageways = from carriageway in dataModelCurrentEntities.Carriageway
                   where carriageway.RoadId == roadId && carriageway.DistanceBreak == false
                   orderby carriageway.CarriagewayStartInMetre
                   select new CarriagewaySummary
                   {
                       StartMetres = carriageway.CarriagewayStartInMetre, 
                       EndMetres = carriageway.CarriagewayEndInMetre
                   };

它以这种形式生成 SQL(LINQ to entity),
SELECT 
Project1.field1 AS field1
Project1.field2 AS field2
FROM ( SELECT 
    Extent1.field1 AS field1, 
    Extent1.field2 AS field2
    FROM table AS Extent1
    WHERE blah
)  AS Project1
ORDER BY blah ASC

这是什么原因?我会认为这样的事情就足够了,
SELECT 
fields
FROM table as Project1
WHERE blah
ORDER BY blah ASC

我记得 LINQ to SQL 会倾向于生成更简单的 SQL。

我看过更复杂的连接等示例,LINQ to entity 似乎生成了更复杂的 SQL。

更新:

这很有趣,因为我试图测试你在说什么,我遇到了这个 LINQ,
var attachments = (from a in entities.Attachments
                  where a.AttachmentID == 749
                  select new {a.AddedOn, a.AddedBy});

这会生成这个 SQL,
SELECT 
[Extent1].[AttachmentID] AS [AttachmentID], 
[Extent1].[AddedOn] AS [AddedOn], 
[Extent1].[AddedBy] AS [AddedBy]
FROM [dbo].[Attachment] AS [Extent1]
WHERE 749 = [Extent1].[AttachmentID]

这个没有子查询。

不同的是(至少其中一个)......等待它。信息。上面生成子查询的第一个查询是使用 informix。第二个查询不是 SQL 服务器。

它可能没有那么简单,因为查询不同。

我确实接受了第二个查询并将其分解为这样的子查询(手动),
SELECT 
[Project1].[AttachmentID] AS [AttachmentID], 
[Project1].[AddedOn] AS [AddedOn], 
[Project1].[AddedBy] AS [AddedBy]

    FROM ( SELECT

    [Extent1].[AttachmentID] AS [AttachmentID], 
    [Extent1].[AddedOn] AS [AddedOn], 
    [Extent1].[AddedBy] AS [AddedBy]
    FROM [dbo].[Attachment] AS [Extent1]
    WHERE 749 = [Extent1].[AttachmentID]
    ) AS Project1

SQL Server 为两者显示了相同的执行计划,因此正如您所说,SQL Server 能够很好地优化它。另一方面,Informix 在优化事物方面是阴暗的。

最佳答案

它是否生成带有子查询的 SQL 可能取决于您使用的 Entity Framework 提供程序。但是由于大多数现有的可能具有相同的谱系(因为它们可能是从 Microsoft 代码示例开始的),它们可能都会产生相似的 SQL。为提供者提供了一个从 Linq 语句生成并负责生成 SQL 的查询树。执行此操作的过程是访问查询树中的节点并生成 SQL。

在 OP 中的给定投影中,生成子查询是有意义的。它要求从前面的“查询”中获取一组值(新 ... {StartMetres,EndMetres})。因此,查询生成将产生 "SELECT <requested values> FROM something" "something"是,本身,呈现为一个查询。因此,对查询树的简单访问会产生子查询。

一旦该过程完成,提供者当然可以“优化”生成的 SQL 并删除子查询。然而,这正是 SQL 查询引擎真正擅长的事情,因此将该任务委托(delegate)给查询引擎是有意义的。这可能取决于您使用的数据库,但带有子查询的 SQL 语句的查询计划很可能与没有子查询的“优化”计划相同。

关于sql - 为什么 Entity Framework 会生成此 SQL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6131527/

相关文章:

linq - 无法创建常量值 - 仅允许原始类型或枚举类型

sql - MySQL 查询太复杂了

sql - 如何使用 scala slick 3 发送纯 SQL 查询(并检索结果)

mysql - 在 LINQ to EF 查询中防止 'NOW()'

c# - Enumerable 中的重复 yield 中断

asp.net-mvc - 将本地列表操作与 linq to entities 数据库操作混合

SQL 多次更新与单次更新性能

java - 如何合并单个sql表中两条记录的相同字段

SQLite 条件 SELECT 语句 - 多个条件但单个语句

c# - 使用 Linq to Entities 的存储函数