2011-05-25 53 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語句與子查詢將與沒有子查詢的「優化」查詢計劃相同。