EF LINQ 包括多个实体和嵌套实体

好的,我有三个层次的实体,它们的层次结构如下: 课程-> 模块-> 章节

以下是 EF LINQ 的原始声明:

Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters))
.Single(x => x.Id == id);

现在,我想包括另一个实体,叫做实验室,它与一个课程相关联。

如何包含 Lab 实体?

我尝试了以下方法,但没有效果:

Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
.Single(x => x.Id == id);

关于第二实体有什么想法吗?

任何一条建议或信息将被高度赞赏。谢谢!

232934 次浏览

你有没有试过再加一个 Include:

Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters))
.Include(i => i.Lab)
.Single(x => x.Id == id);

您的解决方案失败了,因为 Include不采用布尔运算符

Include(i => i.Modules.Select(s => s.Chapters) &&          i.Lab)
^^^                  ^             ^
list           bool operator    other list

更新 要了解更多信息,请下载 LinqPad并查看示例。 我认为这是熟悉 Linq 和 Lambda 最快的方法。

作为一个开始-之间的差异 SelectInclude是一个选择,你决定 什么你想返回(又名投影)。Include 是一个 急切载入函数,它告诉实体框架您希望它包含来自其他表的数据。

包含语法也可以是字符串形式的,如下所示:

           db.Courses
.Include("Module.Chapter")
.Include("Lab")
.Single(x => x.Id == id);

LinqPad的样本更能解释这一点。

Include是连贯接口的一部分,因此可以相继编写多个 Include语句

 db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
.Include(i => i.Lab)
.Single(x => x.Id == id);

你也可以试试

db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);

可以这样写一个扩展方法:

    /// <summary>
/// Includes an array of navigation properties for the specified query
/// </summary>
/// <typeparam name="T">The type of the entity</typeparam>
/// <param name="query">The query to include navigation properties for that</param>
/// <param name="navProperties">The array of navigation properties to include</param>
/// <returns></returns>
public static IQueryable<T> Include<T>(this IQueryable<T> query, params string[] navProperties)
where T : class
{
foreach (var navProperty in navProperties)
query = query.Include(navProperty);


return query;
}

即使在通用实现中也要这样使用它:

string[] includedNavigationProperties = new string[] { "NavProp1.SubNavProp", "NavProp2" };


var query = context.Set<T>()
.Include(includedNavigationProperties);

在实体框架核心(EF.core)中,您可以使用 .ThenInclude来包含下一个级别。

var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToList();

更多信息: https://learn.microsoft.com/en-us/ef/core/querying/related-data

注: 假设你需要 blog.Posts上的多个 ThenInclude(),只需重复 Include(blog => blog.Posts)并做另一个 ThenInclude(post => post.Other)

var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Other)
.ToList();

这是我项目里的

 var saleHeadBranch = await _context.SaleHeadBranch
.Include(d => d.SaleDetailBranch)
.ThenInclude(d => d.Item)
.Where(d => d.BranchId == loginTkn.branchId)
.FirstOrDefaultAsync(d => d.Id == id);

这是我的工作范例。 AccountInfoes 是 User 的父级, 用户是货币和国家的父级。

var accountinfo =  _context.AccountInfoes.Include(a => a.User)
.Include(a=>a.User.Currency)
.Include(a => a.User.Country)
.FirstOrDefaultAsync(ai => ai.UserId == userId);