1

我必须对我的实体框架模型LINQ查询,这是这样的:Linq2Entities +实体框架查询优化:。凡()与LINQ的地方

from e1 in context.Entity1 
from e2 in context.Entity2 
from e3summary in 
    from e3 in context.Entity3 
    where e3.Field1 = value // <-- this is the line in question 
    group e3 by new { e3.Field1, e3.Field2, e3.Field3 } 
     into e3group 
     select new 
     { 
      e3group.Key.Field1, 
      e3group.Key.Field2, 
      e3group.Key.Field3, 
      Total = e3group.Sum(o => o.Field4) 
     } 
where 
    // conditions on e1 and joining e1, e2, and e3summary 
    ... 

select e1; 

生成的SQL从选择我的一切e3表(实际上是数据库中的一个视图)作为派生表,然后对派生表应用where子句,对其进行分组,并加入到其他结果中。这几乎正​​是我想要的,除了我认为我不需要整个e3视图进行分组(它是我的测试数据库中的73M记录,几乎是800M的产品)。我期待在最内层的级别被应用在我的LINQ查询的WHERE子句,而是我得到(我只包括相关部分):

... 
INNER JOIN (SELECT 
    [Extent3].[Field1] AS [K1], 
    [Extent3].[Field2] AS [K2], 
    [Extent3].[Field3] AS [K3], 
    SUM([Extent3].Field4] AS [A1] 
    FROM (SELECT 
     [e3].[ID] AS [ID], 
     [e3].[Field1] AS [Field1], 
     [e3].[Field2] AS [Field2], 
     [e3].[Field3] AS [Field3], 
     [e3].[Field4] AS [Field4], 
     [e3].[Field5] AS [Field5], 
     [e3].[Field6] AS [Field6], 
     [e3].[Field7] AS [Field7], 
     [e3].[Field8] AS [Field8] 
     FROM [dbo].[e3] AS [e3]) AS [Extent3] 
      WHERE ([Extent3].[Field1] = @p__linq__0) 
      GROUP BY [Extent3].[Field1], [Extent3].[Field2], [Extent3].[Field3]) AS [GroupBy1] 
    ... 

我从

改变了我的Linq查询
from e3 in context.Entity3 
    where e3.Field1 = value // <-- this is the line in question 

from e3 in context.Entity3.Where(e => e.Field1 = value) 

,这创造了什么我原先预期,在最内层的级别WHERE子句:

 ... 
     FROM [dbo].[e3] AS [e3] WHERE [e3].Field1] = @p__linq__0) AS [Extent3] 
      GROUP BY [Extent3].[Field1], [Extent3].[Field2], [Extent3].[Field3]) AS [GroupBy1] 

为什么在我的上下文中将.Where([condition])直接应用于集合与在我的Linq查询中有where [condition]有什么区别?我会认为这将以相同的方式被解析到表达式树中。

P.S.在旁注中,将两个查询放入SQL Server Management Studio并比较查询执行计划,我惊讶地发现执行计划无论如何都是完全相同的。 SQL的查询计划优化器确实令人难以置信!

+0

您关于执行计划相同的最后一点是点对点。由于Field5到Field8根本不在父查询中使用,所以优化器在子查询中完全忽略它们。您可以达到的唯一节约是不会通过线路发送多余的字节查询文本。 – 2011-04-14 18:30:07

回答

3

这些查询之间的区别在于表示您使用的构造。所述第一查询被评价为

(from e3 in context.Entity3) where e3.Fied1 == value 

而第二查询作为

from e3 in (context.Entity3.Where(e => e.Field1 == value)) 

虚线语法评价优先,因为它被视为分开的表达子树必须被构造和安装于外的表达式树查询。您可以将其视为子查询,即使最后不必像子查询那样进行子查询,如示例中所示。

+0

所以我应该*总是*使用'.Where([condition])'?虽然我猜SQL查询执行计划的结果会表明它确实无关紧要。 – 2011-04-14 18:30:31

+0

它应该没关系。 – 2011-04-14 18:32:34