我如何热切地将实体的子孙元素包含在实体框架代码优先中?

ado*_*ojp 61 entity-framework eager-loading ef-code-first

想象一下这样的三个实体(客户,书籍,作者):

客户有很多书

一本书有一位作者

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

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
Run Code Online (Sandbox Code Playgroud)

当我查询客户时,我按预期得到了一堆具有以下性质的查询

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

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

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

但我不知道如何加载第三级(作者).我怎样才能做到这一点?

tdy*_*tra 142

此外,没有必要使用字符串重载.这种方法也可以:

var customers = db.Customers.Include(c => c.Books.Select(b => b.Author));
Run Code Online (Sandbox Code Playgroud)

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

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

  • 请注意,要使用此include方法,您需要引用System.Data.Entity (10认同)
  • 我认为这是一种更好的方法,因为它是强类型,而不是字符串Path弱类型. (6认同)
  • 据我所知,这种语法在EF核心中不起作用.如果你引用这个问题,有一个ThenInclude可能是更好的解决方案http://stackoverflow.com/a/38741905/1047812 (4认同)

Mat*_*ton 47

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

var customers = db.Customers.Include("Books.Author");
Run Code Online (Sandbox Code Playgroud)

它看起来很奇怪,因为"作者"不是书籍集合上的财产(而是每本书上的财产),但它有效.给它一个旋转.

  • @jbueno如果可能的话,我会避免使用它们,因为如果更改Customer的属性名称,它们就不会被编译器捕获. (2认同)
  • 根据@ tdykstra的回答你可以使用`Select`. (2认同)
  • 我不认为魔术弦应该被提升为可行的解决方案。他们可以使调试成为一种真正的痛苦。 (2认同)

小智 7

您可以使用ThenInclude关键字:

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