我不太明白为什么这个查询的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对象的内存中。但迹线表明不然。
答案 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();