2012-03-12 64 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

相关问题