Entity framework core EF Core在直接访问之前返回空关系
我有一些模型如下:Entity framework core EF Core在直接访问之前返回空关系,entity-framework-core,lazy-loading,eager-loading,Entity Framework Core,Lazy Loading,Eager Loading,我有一些模型如下: public class Mutant { public long Id { get; set; } ... // Relations public long OriginalCodeId { get; set; } public virtual OriginalCode OriginalCode { get; set; } public int DifficultyLevelId { get; set; } publ
public class Mutant
{
public long Id { get; set; }
...
// Relations
public long OriginalCodeId { get; set; }
public virtual OriginalCode OriginalCode { get; set; }
public int DifficultyLevelId { get; set; }
public virtual DifficultyLevel DifficultyLevel { get; set; }
}
及
现在当我请求突变体时,原始代码为空:
但一旦我要求使用原始代码
s,如下所示:
然后突变体的OriginalCode
字段将不为空:
原因是什么?我如何修复它?在EF核心文档的一节中解释了原因 第一种行为是因为EF Core目前不支持延迟加载,所以通常导航属性将获得
null
,直到您通过急切或显式加载专门加载它们。但是,快速加载部分包含以下内容:
提示EntityFrameworkCore将自动修复以前加载到上下文实例中的任何其他实体的导航属性。因此,即使没有明确包含导航属性的数据,如果以前加载了部分或所有相关实体,也可能会填充该属性 这解释了为什么导航属性在第二种情况下不为null 现在,我不确定您想要修复这两个行为中的哪一个,因此我将尝试解决这两个问题 第一种行为可以通过使用当前可用的加载相关数据的方法之一“修复”,例如,即时加载:
var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();
第二种行为是“设计的”,无法控制。如果要避免这种情况,请确保使用fresh newDbContext
实例仅用于执行单个查询以重试所需的数据
更新:从v2.1开始,EF核心支持。但是,默认情况下它是不启用的,因此为了使用它,应该标记所有导航属性
virtual
,通过UseLazyLoadingProxies
调用安装并启用它,或者使用-这两个都在EF核心文档中用示例进行了解释。您可以猜到,我想要控制第一个行为。但仍然有一个大问题。你提到的这种方式,我应该明确指出需要填补的关系,是吗?确实如此。您必须使用多个Include
/然后使用Include
方法指定要“包括”的每个对象。好吧,有一些计划在将来自动完成,但现在这是唯一的选择。:)谢谢。非常有帮助的回答。现在EF核心支持延迟加载:虽然我认为没有设置为默认值,但这意味着它不是推荐的解决方案!我认为,如果使用正确,非惰性方法更难编写,但对于运行时更好,这将把许多未来的数据库请求放在一个数据库中。
modelBuilder.Entity<Mutant>()
.HasOne(m => m.OriginalCode)
.WithMany(oc => oc.Mutants)
.HasForeignKey(m => m.OriginalCodeId)
.OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);
modelBuilder.Entity<Mutant>()
.HasOne(m => m.DifficultyLevel)
.WithMany(dl => dl.Mutants)
.HasForeignKey(m => m.DifficultyLevelId)
.OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);
var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();