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