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

发布于 2025-01-04 02:47:24 字数 1307 浏览 4 评论 0原文

我不太明白为什么此查询上的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

追我者格杀勿论 2025-01-11 02:47:25

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();

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 use Include on Matter I expect you must also return Matter instances to let the magic do its work. You are using Include on Matter but select ClientContract - the shape of the query has changed.

What happens if you try this:

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文