小编典典

为什么实体框架会生成此SQL?

sql

我有这个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
                   };

它以这种形式(对实体的LINQ)生成SQL,

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似乎会生成更复杂的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。上面生成子查询的第一个查询是使用notifyix。第二个查询不是SQL Server。

它可能不那么简单,因为查询是不同的。

我确实接受了第二个查询,并将其分解成这样的子查询(手动),

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在优化方面是可耻的。


阅读 151

收藏
2021-04-15

共1个答案

小编典典

是否使用子查询生成SQL可能取决于您使用的实体框架提供程序。但是,由于大多数现有程序可能具有相同的血统书(因为它们可能是从Microsoft代码示例开始的),因此它们都可能导致相似的SQL。提供程序将获得一个查询树,该查询树由Linq语句生成,并负责生成SQL。这样做的过程是访问查询树中的节点并随其生成SQL。

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

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

2021-04-15