如何在 Entity Framework Code First 中急切地包含实体的子元素和孙元素?

Posted

技术标签:

【中文标题】如何在 Entity Framework Code First 中急切地包含实体的子元素和孙元素?【英文标题】:How do I eagerly Include the child and grandchild elements of an entity in Entity Framework Code First? 【发布时间】:2011-08-19 19:52:39 【问题描述】:

想象三个相关的实体(客户、书籍、作者)是这样的:

一个客户有很多书

一本书只有一个作者

我使用这些数据来打印这样的报告:

Customer: Peter
  Book: To Kill a Mockingbird - Author: Harper Lee
  Book: A Tale of Two Cities - Author: Charles Dickens
Customer: Melanie
  Book: The Hobbit - Author: J. R. R. Tolkien

当我查询客户时,如预期的那样,我收到一堆具有以下性质的查询

    获取客户的查询 每个客户的查询以获取他的书籍 查询每本书以获取其作者

我可以通过像这样包含书籍来减少查询次数:

var customers = db.Customers.Include(c => c.Books);

但我不知道如何加载第三级(作者)。我该怎么做?

【问题讨论】:

【参考方案1】:

此外,不必使用字符串重载。这个方法也可以:

var customers = db.Customers.Include(c => c.Books.Select(b => b.Author));

有关更多示例,请参阅 EF 团队博客文章: http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

还有本教程: http://www.asp.net/entity-framework/tutorials/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application

【讨论】:

我认为这是一种更好的方法,因为它是强类型,而不是弱类型的字符串路径。 请注意,要使用此包含方法,您需要引用 System.Data.Entity 这是一个很好的问题 - 答案对我来说很重要。我尝试了 6 级深度,虽然它生成的 SQL 查询很大,但它比可能出现的数百个单独的选择语句更有效。 EF 为傻瓜创建 TSQL 的方法! 我无法让 .Select 工作。我最终使用了 .Include(x => x.Books.Author) 据我所知,此语法在 EF 核心中不起作用。如果您参考这个问题***.com/a/38741905/1047812,有一个 ThenInclude 可能是更好的解决方案【参考方案2】:

Include 有一个重载,它接受一个字符串,该字符串可以表示您需要的任何额外属性的完整路径:

var customers = db.Customers.Include("Books.Author");

这看起来很奇怪,因为“作者”不是书籍集合的属性(而是每本书的属性),但它确实有效。试一试。

【讨论】:

@jbueno 如果可能,我会避免使用它们,因为如果您更改客户的属性名称,编译器不会捕获它们。 您可以使用Select,按照@tdykstra 的回答。 我不认为魔术字符串应该被推广为一种可行的解决方案。他们可以让调试变得非常痛苦。 西里尔在下面有正确的答案,.ThenInclude。你不应该使用字符串。 docs.microsoft.com/en-us/ef/core/querying/related-data【参考方案3】:

你可以使用ThenInclude关键字:

var customers = db.Customers.Include(c => c.Books).ThenInclude(book => book.Author));

【讨论】:

以上是关于如何在 Entity Framework Code First 中急切地包含实体的子元素和孙元素?的主要内容,如果未能解决你的问题,请参考以下文章