You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core 默认启用懒加载时,如何正确实现导航属性的预先加载?

问题解答

你给出的Include写法是完全可用的,即便你全局开启了懒加载代理,预加载的优先级也更高,不会和懒加载配置冲突。

核心原理

EF Core 中Include方法的作用就是触发预加载,执行查询时会生成包含JOIN逻辑的SQL语句,一次性将主实体和你指定的关联导航属性数据全部拉取到内存中,后续访问这些已经预加载的导航属性时,不会再触发额外的数据库查询,完全满足你减少数据库请求次数的需求。

不同场景的正确实现

  1. 单层级导航属性预加载
    就是你写的写法,注意异步调用需要加await,所在方法需要声明为async,完整示例:
// 异步查询必须加await,方法返回值改为Task<List<MyObject>>
var dataList = await dbContext.MyObjects
    .Include(o => o.NavigationProperty)
    .ToListAsync();

如果需要同时加载多个同级导航属性,链式调用多个Include即可:

var dataList = await dbContext.MyObjects
    .Include(o => o.NavProp1)
    .Include(o => o.NavProp2)
    .ToListAsync();
  1. 嵌套多层导航属性预加载
    如果需要加载导航属性下的子级关联数据,搭配ThenInclude方法实现:
// 加载MyObject -> NavProp -> SubNavProp的三级数据
var dataList = await dbContext.MyObjects
    .Include(o => o.NavProp)
        .ThenInclude(n => n.SubNavProp)
    .ToListAsync();

大型集合场景的优化建议

你提到处理的是大型对象集合,可结合以下方案进一步优化性能:

  • 如果只需要用到实体和关联属性的部分字段,优先用Select投影查询,不需要依赖预加载和懒加载,性能开销更低:
// 只查询需要的字段,避免加载冗余数据
var result = await dbContext.MyObjects
    .Select(o => new 
    {
        o.Id,
        o.Title,
        NavContent = o.NavProp.Content
    })
    .ToListAsync();
  • 如果关联的是数据量较大的集合导航属性,可开启拆分查询避免笛卡尔积冗余数据,EF Core 5+ 支持:
var dataList = await dbContext.MyObjects
    .Include(o => o.LargeCollectionNavProp)
    .AsSplitQuery() // 拆分为主实体、关联集合两条SQL查询,避免大量重复数据
    .ToListAsync();
  • 如果查询后不需要修改实体,可追加AsNoTracking关闭实体跟踪,既可以提升查询性能,也能避免误访问未预加载的导航属性时触发额外的懒加载查询。

内容的提问来源于stack exchange,提问作者Maksim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 23:45:03