2011-05-25 63 views
12

我有这样的LINQ语句,为什么实体框架生成这个SQL?

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到实体),

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 

,这是什么原因何在呢?我会认为这样的东西已经足够了,我记得LINQ to SQL会倾向于生成更简单的SQL。

我看过更复杂的例子,连接等,和LINQ到实体似乎生成更复杂的SQL。

UPDATE:

这很有趣,因为我是想测试一下你说的话,我碰到这个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的。上面生成子查询的第一个查询使用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服务器显示了两种相同的执行计划,所以就像你说的SQL服务器能够优化它相当好。另一方面,Informix在优化事物方面是阴暗的。

回答

7

它是否生成带有子查询的SQL可能取决于您正在使用的实体框架提供程序。但由于大多数现有的可能共享相同的谱系(因为它们可能从Microsoft代码示例开始),它们可能都会导致类似的SQL。该提供者被给予一个由Linq语句生成的查询树,并负责生成SQL。执行此操作的过程是访问查询树中的节点并生成SQL。

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

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