使用急切加载时,实体框架是不是将所有相关实体加载到无限深度
Posted
技术标签:
【中文标题】使用急切加载时,实体框架是不是将所有相关实体加载到无限深度【英文标题】:Does Entity Framework load all related entities to unlimited depth when using eager loading使用急切加载时,实体框架是否将所有相关实体加载到无限深度 【发布时间】:2019-08-17 12:08:27 【问题描述】:我尝试搜索,但在 docs.microsoft 上找不到确切答案:https://docs.microsoft.com/en-us/ef/core/querying/related-data#eager-loading
我有这段代码:
await MyDbContext.Users.Where(u => u.Id == Id).Include(u => u.UserContacts).ThenInclude(uC => uC.Contact);
返回类型是 User
类型,Contact
也是 User
类型。
当我调试并单步执行时,似乎所有必需的User
的Contact
s 以及它们的所有Contact
s 以及它们的所有Contact
s 都已加载,等等.
问题:
-
这是 EF 的预期行为吗?如果是的话,这不会影响性能吗?必须将 DB 查找到如此深度?
有没有办法让我指定一种“最大深度”?
与我在这里问的最接近的匹配可能是这个 SO 线程: How does Entity Framework work with recursive hierarchies? Include() seems not to work with it
【问题讨论】:
我找到了这个帖子:***.com/questions/53174003/…。答案表明它只是让我“瞥见”相关子代的调试器。不确定这是否就是全部,或者返回的对象是否实际上包含这些深度引用?还是一头雾水。 您可以检查结果查询是什么(它出现在输出窗口中)。这将只是用户表与自身的连接。您确定在之前的查询中没有在相同的上下文中加载用户吗?如果它们已经加载,那么即使您没有要求加载它们,您也会看到它们。 @JerMah 谢谢你。是的,我自己得到了用户表的连接。鉴于包含和关系,我希望如此。但是连接不是无限深度吗?也没有,因为我正在调试第一个查询,所以之前肯定没有加载其他用户。 【参考方案1】:您可以在两种情况下导航到您的预加载查询未指定的实体:
导航属性修复如果同一 DbContext 上的查询或先前查询已加载作为导航属性目标的实体,则更改跟踪器将“修复”导航属性。
延迟加载显然,如果启用延迟加载,导航属性将在您访问它们时加载。
【讨论】:
谢谢大卫。可以肯定的是,此应用程序中没有启用延迟加载,因为如果我没有明确包含它们,我的导航属性将为空。 Fix-UP 会影响调试器吗?因为当我展开查看导航属性的详细信息时,它不会立即出现,而是调试器似乎需要时间来“评估”它。 这听起来像延迟加载。如果您有 IntelliTrace,您可以在调试时看到查询事件。 docs.microsoft.com/en-us/visualstudio/debugger/… 如果它确实是延迟加载,我应该能够在我的示例中不明确地使用Include
,而是执行以下操作:var contacts = user?.UserContacts.ToList()
。正确的?然而,这是行不通的。如果我尝试这样做,我会得到一个 Null 异常。调试器也不喜欢我检查 UserContacts
中的 User
对象,我在没有指定 Include
的情况下查询了该对象。
@David-Browne-Microsoft 好吧,事实证明,我没有明确要求的 Contact
s 可能是由于另一个 Include
而导致我更进一步包含列表,其中可能加载了这些实体,使其看起来像是下降到无限深度。以上是关于使用急切加载时,实体框架是不是将所有相关实体加载到无限深度的主要内容,如果未能解决你的问题,请参考以下文章