2012-03-12 51 views
3

我試圖理解爲什麼LINQ的正在生成SQL這是下面的語句:爲什麼Linq2SQL生成嵌套查詢而不是使用JOIN?

var dlo = new DataLoadOptions(); 
dlo.LoadWith<TemplateNode>(x => x.TemplateElement); 
db.LoadOptions = dlo; 

var data = from node in db.TemplateNodes 
      where node.TemplateId == someValue 
      orderby node.Left 
      select node; 

生成的SQL語句:

SELECT [t2].[Id], 
     [t2].[ParentId], 
     [t2].[TemplateId], 
     [t2].[ElementId], 
     [t2].[Left] AS [Left], 
     [t2].[Right] AS [Right], 
     [t2].[Id2], 
     [t2].[Content] 
FROM (SELECT ROW_NUMBER() OVER (ORDER BY [t0].[Left]) AS [ROW_NUMBER], 
       [t0].[Id], 
       [t0].[ParentId], 
       [t0].[TemplateId], 
       [t0].[ElementId], 
       [t0].[Left], 
       [t0].[Right], 
       [t1].[Id]        AS [Id2], 
       [t1].[Content] 
     FROM [dbo].[TemplateNode] AS [t0] 
       INNER JOIN [dbo].[TemplateElement] AS [t1] 
       ON [t1].[Id] = [t0].[ElementId] 
     WHERE [t0].[TemplateId] = 16 /* @p0 */) AS [t2] 
WHERE [t2].[ROW_NUMBER] > 1 /* @p1 */ 
ORDER BY [t2].[ROW_NUMBER] 

有從TemplateNode.ElementId的外鍵TemplateElement.Id

我本來期望查詢產生JOIN,像這樣:

SELECT * FROM TemplateNode 
INNER JOIN TemplateElement ON TemplateNode.ElementId = TemplateElement.Id 
WHERE TemplateNode.TemplateId = @TemplateId 

按在the answers to this question我已經異型查詢和JOIN的建議比嵌套查詢快3倍。

我正在使用.NET 4.0 Windows窗體應用程序與SQL Server 2008 SP2 64位開發人員版進行測試。

回答

1

LINQ-SQL生成ROW_NUMBER查詢的唯一原因是由於Skip方法。就像上面的SQL看起來一樣,我認爲在T-SQL中沒有像MySQL的Limit 10,25這樣的簡單分頁結構,所以當你使用SkipTake時,你會得到上面的SQL。

我假設有一個Skip用於分頁目的,而LINQ-SQL正在修改查詢。如果您使用像LINQ-Pad這樣的應用程序,則可以運行不同的LINQ查詢來查看其生成的SQL。

0

您的加入示例並不等同。您無法獲取ROW_NUMBER,並隨後通過簡單連接僅選擇行WHERE ROW_NUMBER> 1的行。你必須做一個子選擇或類似的才能得到這個結果。

+0

本,謝謝你的回答。我不確定你沒有誤解我的問題。我不是在'ROW_NUMBER'之後,我只想在第二個SQL語句中使用'JOIN'的結果,但是Linq2SQL正在生成第一個含有子查詢的查詢。我想知道是什麼導致這種情況,以便我可以緩解它。 – 2012-03-12 18:44:13

相關問題