EF Core 3.1中实体的导航属性初始化时机是什么?
EF Core 3.1 导航属性初始化规则说明
核心规则
- 显式加载规则:仅主动调用
Include/ThenInclude关联查询、或调用Load方法手动加载关联实体时,导航属性才会被主动赋值,这是最可控的加载逻辑。 - 变更跟踪器自动补全规则:这是你遇到问题的核心原因,EF Core默认开启变更跟踪功能,只要当前DbContext实例的本地缓存中,已经存在和当前实体外键值匹配的关联实体,就会自动将该关联实体赋值到对应导航属性上,该行为和是否禁用懒加载无关。
现象原因说明
你的SomeOtherType导航属性被自动初始化,说明执行插入操作前,当前DbContext实例已经查询/跟踪过Id为185的SomeOtherType实体,本地缓存中存在该对象,插入新的SomeObj后EF Core自动完成了导航属性关联;而Id为1的SomeType实体未被当前DbContext跟踪过,因此不会自动赋值。
你在LINQPad中无法复现是因为LINQPad每次运行默认会创建全新的DbContext实例,变更跟踪器缓存为空,因此不会触发自动补全逻辑,符合你的预期。
替代优化方案
你当前使用Include重新查询的方案是可行的,针对不同场景还有更高效的选择:
- 如果不需要自动补全导航属性,可以临时关闭变更自动检测,操作完成后恢复即可:
context.ChangeTracker.AutoDetectChangesEnabled = false; // 执行批量插入操作 context.SaveChanges(); context.ChangeTracker.AutoDetectChangesEnabled = true;
- 批量插入场景下,建议所有插入操作完成后,统一做一次批量关联查询,避免单条插入单条查询带来的性能损耗。
内容的提问来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

