期望实体框架的 ObjectQuery(Of T).Include 方法表现不同
我不太明白为什么此查询上的 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,最后一个实体有一个名为 Name 的导航属性 链接到名称实体。
跟踪 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 调用来查找名称。
例如
...
FROM (SELECT ... FROM [dbo].[HBM_NAME] AS [HBM_NAME]) AS [Extent1]
WHERE [Extent1].[NAME_UNO] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=204629
,我本以为 Include 会将返回的 ClientContact 对象的 Name 实体带入内存。但痕迹表明并非如此。
I'm not quite understanding why the Include clause on this query
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;
and the subsequent navigation property references made on the resultant ClientContact entities is not satistifed with a single SQL call. The Matter entity has many MatterContact and each one of those links to a single ClientContact and this last entity has a navigation property called Name which links to a Name entity.
When tracing the SQL, I see that my Include clause has caused joins to happen all the way down to the table containting the Name entity. Here is an extraction of the joins I am seeing:
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]
So I see the joins happening all the way through the hierarchy. However, when I access the properties of the Name entity (e.g. .Name.FirstName), I see additional SQL calls to look up the name.
e.g.
...
FROM (SELECT ... FROM [dbo].[HBM_NAME] AS [HBM_NAME]) AS [Extent1]
WHERE [Extent1].[NAME_UNO] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=204629
I would have thought that the Include would have brought the Name entity into memory for the returned ClientContact objects. But the trace would indicate otherwise.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Include
的共同规则是,仅当您不使用投影或自定义联接时它才有效。我认为真正的规则是:查询的形状不得改变。如果您在Matter
上使用Include
,我希望您还必须返回Matter
实例才能让魔法发挥作用。您在Matter
上使用Include
,但选择ClientContract
- 查询的形状已更改。如果你尝试这样做会发生什么:
Common rule of
Include
is that it works only if you don't use projection or custom join. I think the real rule is: Shape of the query mustn't change. If you useInclude
onMatter
I expect you must also returnMatter
instances to let the magic do its work. You are usingInclude
onMatter
but selectClientContract
- the shape of the query has changed.What happens if you try this: