2012-02-09 68 views
0

我不太理解爲什麼這個查詢預計實體框架的的ObjectQuery(Of T)已.INCLUDE方法不同的行爲

from m in _cmsDb.Matters.Include("MatterContacts.ClientContact.Name") 
    where m.CLIENT_CODE == clientCode && m.MATTER_CODE == matterCode 
from mc in m.MatterContacts 
select mc.ClientContact; 

和隨後的導航屬性引用在得到ClientContact實體提出的條款包括並不滿足於單個SQL調用。該物質實體有許多MatterContact和這些鏈接中的每一個單一的ClientContact這最後的實體有一個名爲名稱其鏈接到名稱實體導航屬性。

在跟蹤SQL時,我看到我的Include子句導致連接一直髮生到包含名稱實體的表。這裏是我看到的連接的提取:

HBM_MATTER INNER JOIN [dbo].[HBA_MATTER_CONT] AS [Extent2] ON [Extent1].[MATTER_UNO] = [Extent2].[MATTER_UNO] 
LEFT OUTER JOIN (... FROM [dbo].[HBA_CLIENT_CONT] AS [HBA_CLIENT_CONT]) AS [Extent3] ON [Extent2].[CONTACT_UNO] = [Extent3].[CONTACT_UNO]) 
FROM [dbo].[HBM_NAME] AS [HBM_NAME]) AS [Extent4] ON [Extent3].[NAME_UNO] = [Extent4].[NAME_UNO] 

因此,我看到連接貫穿整個層次結構。但是,當我訪問Name實體的屬性(例如.Name.FirstName)時,我會看到額外的SQL調用來查找名稱。

例如

... 
FROM (SELECT ...  FROM [dbo].[HBM_NAME] AS [HBM_NAME]) AS [Extent1] 
WHERE [Extent1].[NAME_UNO] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=204629 

我以爲Include會將Name實體帶入內存中,以返回ClientContact對象。但痕跡會另有說明。

回答

1

Include的共同規則是,它只適用於不使用投影或自定義連接的情況。我認爲真正的規則是:查詢的形狀不能改變。如果您在Matter上使用Include,我希望您還必須返回Matter實例,以讓魔法執行其工作。您在Matter上使用Include,但選擇ClientContract - 查詢的形狀已更改。

會發生什麼事,如果你嘗試這個辦法:在金錢

ObjectQuery<ClientContract> query = (ObjectQuery<ClientContract>) 
    (from m in _cmsDb.Matters where m.CLIENT_CODE == clientCode && m.MATTER_CODE == matterCode 
    from mc in m.MatterContacts 
    select mc.ClientContact); 

var data = query.Include("Name").ToList(); 
+0

權!按照您的預計,您的替代組合會產生一個SQL查詢。 (雖然由於某種原因,名稱表包含兩次)。 – 2012-02-09 20:17:36