EF Core 关联数据加载核心是 Include,用于一次性获取主表及关联数据以避免 N+1 问题;多层用 ThenInclude 链式调用;可结合 Where、OrderBy、Take 过滤;需警惕笛卡尔积、深层嵌套和性能损耗。

EF Core 加载关联数据,核心就是 Include —— 它让你在查主表时,顺带把相关联的数据一次性拉回来,避免 N+1 查询问题。不用手动写 JOIN,也不用拆成多次查询,写法清晰、执行高效。
什么时候必须用 Include?
导航属性(比如 Order.Customer 或 Blog.Posts)默认不会自动加载数据。直接访问会报错或返回 null(除非开了延迟加载)。想安全取到关联对象,就得显式告诉 EF Core:“这个也要一起查”。
- 查订单时想同时拿到客户信息 → 用
Include(o => o.Customer) - 查博客时想带上所有文章 → 用
Include(b => b.Posts) - 查文章时既要作者,又要作者的联系方式 → 先
Include(p => p.Author),再ThenInclude(a => a.ContactInfo)
怎么加载多层关联?用 ThenInclude 链起来
一层不够?比如“订单 → 订单项 → 商品”,就靠 ThenInclude 往下钻。它只能跟在 Include 或另一个 ThenInclude 后面,不能单独用。
-
.Include(o => o.OrderItems).ThenInclude(oi => oi.Product):订单 + 所有订单项 + 每个订单项对应的商品 -
.Include(b => b.Posts).ThenInclude(p => p.Author).ThenInclude(a => a.Profile):博客 + 文章 + 作者 + 作者资料 - 多个同级关系可并列写:
.Include(b => b.Author).Include(b => b.Posts),互不干扰
怎么只加载部分关联数据?加 Where 过滤
默认 Include 会拉出全部关联记录。但有时你只需要“2025 年的订单项”或“已发布的文章”,这时可以在 Include 内部做条件筛选:
.Include(o => o.OrderItems.Where(oi => oi.CreatedYear == 2025)).Include(b => b.Posts.Where(p => p.IsPublished))- 还能配合
OrderBy或Take,比如只取最新 3 篇文章:.Include(b => b.Posts.OrderByDescending(p => p.PublishDate).Take(3))
性能和常见坑点提醒
Include 好用,但乱用容易翻车:
- 一对多关系里反复 Include 多个集合,可能触发笛卡尔积,结果行数暴增
- 深层嵌套(比如四级以上)会让 SQL 变复杂,影响可读性和执行效率
- 如果只用关联字段中的个别字段,建议用
Select投影代替全实体加载,更轻量 - 不需要跟踪实体状态时,加上
.AsNoTracking()能明显提速
基本上就这些。写对 Include 和 ThenInclude,关联查询就稳了一大半。










