EF Core预加载怎么用 EF Core Eager Loading (Include)教程

来源:这里教程网 时间:2026-02-21 17:33:31 作者:

EF Core 预加载(Eager Loading)就是用 Include 主动把关联数据一次性查出来,避免访问导航属性时反复查库——这是解决 N+1 查询问题最直接有效的方式。

Include 基本用法:加载一级关联

只需在查询链中调用

.Include(x => x.NavigationProperty)
,EF Core 就会在生成 SQL 时自动加 JOIN 或发批量查询:

对引用类型(如
Post.Author
),通常生成 LEFT JOIN
对集合类型(如
Blog.Posts
),默认用单独的 IN 查询(避免笛卡尔积),也可配成 JOIN
必须用 Lambda 表达式,不能写字符串,否则编译不通过

示例:

var posts = context.Posts
    .Include(p => p.Author)
    .Include(p => p.Comments)
    .ToList();

ThenInclude:加载多级嵌套关系

当关联再往下一层(比如作者还有 Profile,评论还有 Reply),就得接 ThenInclude

它只能跟在
Include
或上一个
ThenInclude
后面
每级都必须指向“上一级导航属性”的子属性,类型要严格匹配 支持集合→引用、集合→集合、引用→引用等组合

示例(三级加载):

var blogs = context.Blogs
    .Include(b => b.Posts)          // Blog → Posts(集合)
        .ThenInclude(p => p.Author) // Posts → Author(引用)
            .ThenInclude(a => a.Profile) // Author → Profile(引用)
    .ToList();

同时加载多个同级导航属性

一个实体常有多个独立的一级关联,比如博客既有文章,又有标签、分类:

重复调用
Include
即可,顺序无关
EF Core 会为每个
Include
生成独立的 JOIN 或批量查询
注意:不要对同一个导航属性多次
Include
,会报错

示例:

var blogs = context.Blogs
    .Include(b => b.Posts)
    .Include(b => b.Tags)
    .Include(b => b.Category)
    .ToList();

实用提醒:别踩这些坑

预加载不是越多越好,几个关键点得心里有数:

分页前一定要先
Include
,否则
Take(10)
可能因 JOIN 导致结果重复或数量不准
一对多关系下过度
Include
容易引发数据膨胀(比如 1 个博客 + 100 篇文章 + 每篇 5 条评论 = 500 行结果)
不需要全部字段时,优先考虑
Select
投影,比全量
Include
更轻量
若只想查部分子项(如只加载最近 3 条评论),
Include
本身不支持过滤,得换思路(如用 GroupJoin 或显式查询)

基本上就这些。用好

Include
ThenInclude
不复杂,但容易忽略时机和层级约束。

相关推荐