期望实体框架的ObjectQuery(Of T).Include方法以表现不同

时间:2012-02-09 19:30:19

标签: sql entity-framework linq-to-entities

我不太明白为什么这个查询的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调用。 Matter 实体有许多 MatterContact ,每个链接指向一个 ClientContact ,而这最后一个实体都有一个名为名称的导航属性,链接到名称实体。

在跟踪SQL时,我看到我的Include子句导致连接一直发生到包含 Name 实体的表。这是我看到的连接的提取:

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调用来查找名称。

e.g。

...
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 个答案:

答案 0 :(得分:1)

Include的通用规则是,只有在不使用投影或自定义连接时,它才有效。我认为真正的规则是:查询的形状不得改变。如果您在Include上使用Matter,我希望您还必须返回Matter个实例才能让魔法发挥作用。您在Include上使用Matter,但选择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();