最直接有效的办法是用Include显式预加载关联数据,把1+N次查询压成1次JOIN查询;禁用延迟加载,避免N+1;多级关系用ThenInclude链式加载;笛卡尔爆炸时用AsSplitQuery拆分查询;只读场景优先Select投影DTO并AsNoTracking。

最直接有效的办法是用 Include 显式预加载关联数据,把原本 1+N 次查询压成 1 次 JOIN 查询。别依赖延迟加载,尤其在循环里访问导航属性时,N+1 就悄悄发生了。
用 Include + ThenInclude 一次性加载多级关系
适用于需要完整对象图的场景,比如查博客、文章、作者、评论四级数据:
- 一级包含:`.Include(b => b.Posts)` 加载所有文章
- 二级延伸:`.ThenInclude(p => p.Author)` 加载每篇文章的作者
- 三级延伸:`.ThenInclude(a => a.Profile)` 再加载作者档案(支持链式调用)
EF Core 会生成一条含多个 JOIN 的 SQL,避免逐条查询。注意:导航路径必须连续,不能跳级(如不能从 Blog 直接 ThenInclude 到 Comment)。
拆分查询 + 内存关联(Split Queries)
当多级 Include 导致笛卡尔爆炸(比如 1 个订单 × 10 商品 × 5 日志 = 50 行重复数据),可改用独立查询:
- EF Core 5+ 支持 `.AsSplitQuery()`,让每个 Include 变成单独 SQL,再由 EF 在内存中按主键/外键自动关联
- 比单条 JOIN 更省内存和网络带宽,适合子集合数据量大的情况
- 写法示例:
.AsSplitQuery().Include(o => o.Items).ThenInclude(i => i.Logs)
用 Select 投影最小化数据(推荐高频只读接口)
根本不需要整个实体?那就别加载实体,直接取字段:
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~