EF Core 延迟加载导致关系属性为空
问题:
当获取包含关联数据的实体时,在执行显式加载之前,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>
关系在 OnModelCreating
方法中配置:
<code class="language-csharp">modelBuilder.Entity<Mutant>() .HasOne(m => m.OriginalCode) .WithMany(oc => oc.Mutants) .HasForeignKey(m => m.OriginalCodeId);</code>
问题:
最初,通过查询检索到的 Mutant 实体的 OriginalCode
属性为 null。但是,在单独的查询中访问 OriginalCodes
集合会填充 OriginalCode
属性。
解释:
EF Core 默认情况下不支持延迟加载。关系不会被急切加载,除非明确请求。在第一个场景中,由于 OriginalCode
关系没有在查询中显式包含,因此它保持为 null。
解决方案:
有两种方法可以解决此行为:
1. 急切加载:
使用 Include()
在查询中显式包含相关数据:
<code class="language-csharp">var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();</code>
2. 使用延迟加载:
从 EF Core 2.1 开始,支持延迟加载。但是,这需要通过 UseLazyLoadingProxies()
启用并使用虚拟导航属性。
<code class="language-csharp">modelBuilder.UseLazyLoadingProxies(); public class Mutant { public long Id { get; set; } public long OriginalCodeId { get; set; } public virtual OriginalCode OriginalCode { get; set; } }</code>
阻止自动填充:
如果不需要自动填充关系,可以通过为每个查询使用新的 DbContext 实例或使用 AsNoTracking()
进行无跟踪查询来阻止它。
以上是为什么 EF Core 关系在显式加载之前一直为空?的详细内容。更多信息请关注PHP中文网其他相关文章!