EF Core 延迟加载导航属性的空值问题及解决方案
问题描述
考虑以下模型:
<code class="language-csharp">public class Mutant { public long Id { get; set; } public long OriginalCodeId { get; set; } public virtual OriginalCode OriginalCode { get; set; } } public class OriginalCode { public long Id { get; set; } public virtual List<Mutant> Mutants { get; set; } }</code>
在 DbContext 的 OnModelCreating
方法中定义关系:
<code class="language-csharp">modelBuilder.Entity<Mutant>() .HasOne(m => m.OriginalCode) .WithMany(oc => oc.Mutants) .HasForeignKey(m => m.OriginalCodeId) .OnDelete(DeleteBehavior.Restrict);</code>
当查询 Mutant 时,OriginalCode
属性最初为空。但是,如果在查询 Mutant 之前先查询 OriginalCode
,则 OriginalCode
属性会被填充。
原因分析
EF Core 文档的“加载相关数据”部分对此行为进行了说明:
Entity Framework Core 目前不支持延迟加载,因此通常情况下,在您通过预加载或显式加载它们之前,导航属性将为空。
然而,“预加载”部分包含以下内容:
提示 Entity Framework Core 将自动修复任何先前已加载到上下文实例中的其他实体的导航属性。因此,即使您没有显式包含导航属性的数据,如果先前已加载部分或全部相关实体,该属性仍可能被填充。
解决方案
解决第一个问题(导航属性为空):
使用可用的加载相关数据的方法,例如预加载:
<code class="language-csharp">var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();</code>
解决第二个问题(预先加载相关实体导致导航属性被填充):
此行为是“设计使然”,无法控制。为避免此问题:
AsNoTracking()
)。EF Core v2.1 及更高版本更新:
EF Core v2.1 支持延迟加载,但默认情况下未启用。要启用它:
virtual
。Microsoft.EntityFrameworkCore.Proxies
NuGet 包。UseLazyLoadingProxies()
启用延迟加载。通过以上方法,您可以有效地管理 EF Core 中的导航属性加载,避免空值问题并提高代码的可预测性。
以上是为什么 EF Core 导航属性在显式加载之前为空,以及如何一致地填充它们?的详细内容。更多信息请关注PHP中文网其他相关文章!