EF LINQ 包括多个和嵌套的实体
Posted
技术标签:
【中文标题】EF LINQ 包括多个和嵌套的实体【英文标题】:EF LINQ include multiple and nested entities 【发布时间】:2013-03-23 18:35:25 【问题描述】:好的,我有具有以下层次结构的三级实体:课程 -> 模块 -> 章节
这是原始的 EF LINQ 语句:
Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters))
.Single(x => x.Id == id);
现在,我想包含另一个名为 Lab 的实体,它与课程相关联。
如何包含 Lab 实体?
我尝试了以下方法,但没有成功:
Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
.Single(x => x.Id == id);
关于包含第二个实体的任何想法?
我们将不胜感激任何建议或信息。谢谢!
【问题讨论】:
添加另一个.Include
应该可以工作,除非您的意思是附加的包含是 Course 的孙子。 See this 或 better option is this
***.com/q/3356541的相关/可能重复
【参考方案1】:
您是否尝试过添加另一个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 的最快方法。
首先 - Select
和 Include
之间的区别在于,您可以通过 Select 决定 要返回的内容(也称为投影)。 Include 是一个 Eager Loading 函数,它告诉 Entity Framework 您希望它包含来自其他表的数据。
Include 语法也可以是字符串。像这样:
db.Courses
.Include("Module.Chapter")
.Include("Lab")
.Single(x => x.Id == id);
但LinqPad 中的示例更好地解释了这一点。
【讨论】:
欣赏!我在哪里可以了解更多信息?我对 Include 和 Select 之间的区别特别感兴趣 只有这个对我有用:.Include("Module.Chapter")
。知道为什么会这样吗?
@JoSmo 您需要导入命名空间System.Data.Enity
才能访问扩展方法。更多信息here
using System.Data.Entity;
做到了。谢谢!
因提及出色的 linqpad 以及使用 System.Data.Entity 的提示而被投票赞成,感谢 Jens【参考方案2】:
在 Entity Framework Core (EF.core
) 中,您可以使用 .ThenInclude
来包含下一个级别。
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToList();
更多信息:https://docs.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();
【讨论】:
在 EF.core 中我似乎无法执行 .Include(i => i.Modules.Select(s => s.Chapters)),特别是 .Include 中的 .Select。任何人都可以确认或交谈吗? @ttugates 你打算用这个选择做什么?我认为您想要做的正是您在 EF 核心中使用ThenInclude
所做的事情。也许提出一个很好的例子,以便我们回答它。
@Nick N - Entity Framework Linq Query: How to Where on Multiple Nav Properties and Select from 3rd Nav Property。因为我选择的不是我要匹配的,所以不需要包含,所以问题是切线的。我的问题可能过于“狭隘”,但感谢您的帮助。
啊。实际上, .ThenInclude() 确实有效。智能感知显示相关表格只需要很长时间。【参考方案3】:
Include
是fluent interface的一部分,所以你可以写多个Include
语句一个接一个
db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
.Include(i => i.Lab)
.Single(x => x.Id == id);
【讨论】:
欣赏!你能指出我在哪里可以学到更多吗?谢谢! 如果 Modules 有多个要加入的表,你知道语法是什么吗?说它链接到章节和其他内容? 是 .Net 的 fluent 部分还是需要安装的库?【参考方案4】:你也可以试试
db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);
【讨论】:
谢谢 - 字符串中的点符号非常有用 这很有用,但是,不使用它的一个原因是以后易于重构:如果您在某个时候重命名“章节”实体,另一个示例将自动重命名。另一个是错误会更快被发现:在编译时,而不是运行时。 @MGOwen 我同意你的评论。但是,也可以使用:db.Courses.Include($"nameof(Modules).nameof(Chapters)").Single(c => c.Id == id);
。【参考方案5】:
可以这样写一个扩展方法:
/// <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);
【讨论】:
我正在尝试您的答案,但由于自身存在无限循环,它会抛出 ***exceptions。 @VictoriaS.,你可以重命名扩展方法,这样就不会干扰真正的Include
【参考方案6】:
这是我的项目
var saleHeadBranch = await _context.SaleHeadBranch
.Include(d => d.SaleDetailBranch)
.ThenInclude(d => d.Item)
.Where(d => d.BranchId == loginTkn.branchId)
.FirstOrDefaultAsync(d => d.Id == id);
【讨论】:
感谢您抽出宝贵时间提供答案。!你能:- 1)编辑你的答案,以便详细回答。 2)解释你想用这个答案实现什么以及你想说什么。?有关更多信息,请参阅如何在帮助中心写出好的答案(如何提问:***.com/help/how-to-answer) var saleHeadBranch = await _context.SaleHeadBranch .Include(d => d.SaleDetailBranch) .Include("SaleDetailBranch.Item") .Where(d => d.BranchId == loginTkn.branchId) 。 FirstOrDefaultAsync(d => d.Id == id);以上是关于EF LINQ 包括多个和嵌套的实体的主要内容,如果未能解决你的问题,请参考以下文章
EF Core 嵌套 Linq 选择导致 N + 1 个 SQL 查询