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

EF Core 2.1未使用Include却加载关联属性的原因咨询

EF Core中导航属性自动填充与Include的使用场景

问题背景

我们在项目中使用Entity Framework Core 2.1.14,HouseholdMmbrPrfl与HouseholdMemberIncomes为一对多关系。执行以下两段代码时,生成的SQL不同,但都返回了关联属性:

// test1: 未使用Include
var test1 = await _dbContext.HouseholdMmbrPrfl
                            .Where(x => x.HouseholdMemberProfileId == memberId)
                            .FirstOrDefaultAsync();

// test2: 使用Include
var test2 = await _dbContext.HouseholdMmbrPrfl
                            .Include(x => x.HouseholdMemberIncomes)
                            .Where(x => x.HouseholdMemberProfileId == memberId)
                            .FirstOrDefaultAsync();

test1仅查询HouseholdMmbrPrfl表,但导航属性HouseholdMemberIncomes已被填充;test2执行两次查询(分别针对主表和关联表)。我们未启用UseLazyLoadingProxies,且导航属性并非虚拟:

public List<HouseholdMemberIncome> HouseholdMemberIncomes { get; set; }

核心原因:EF Core的关系修复(Relationship Fixup)

test1中导航属性被自动填充,是EF Core的关系修复机制在起作用:

  • 当当前DbContext实例的一级缓存中,已经存在与HouseholdMmbrPrfl关联的HouseholdMemberIncome实体时,EF Core会自动将这些缓存的子实体填充到主实体的导航属性中。
  • 这种情况下不会触发额外SQL查询,因为数据已经存在于上下文缓存里。

什么时候需要使用Include?

虽然关系修复能自动填充导航属性,但它依赖上下文缓存的存在,不可靠。必须使用Include的场景包括:

  • 上下文无关联数据缓存时:如果是新的DbContext实例,或者之前从未查询过对应的关联数据,不使用Include的话,导航属性会是null(或空集合,取决于属性初始化方式)。
  • 确保主动加载关联数据:当你需要在查询主实体的同时,明确加载关联数据,避免后续因为缓存不存在导致导航属性为空的情况。
  • 控制查询计划:使用Include可以让EF Core生成明确的关联查询(EF Core 2.1中一对多默认是两次独立查询,后续版本支持合并为单查询),确保数据加载的确定性。

额外说明

你的场景中可以排除懒加载:懒加载要求导航属性为虚拟类型,且必须启用UseLazyLoadingProxies,而你的代码都不满足这两个条件,所以不存在懒加载触发的可能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:15:58