Con*_*ver 21 entity-framework-core
我有一些类似下面的模型:
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; }
}
Run Code Online (Sandbox Code Playgroud)
和
public class OriginalCode
{
public long Id { get; set; }
...
// Relations
public virtual List<Mutant> Mutants { get; set; }
public virtual List<OriginalCodeInputParameter> OriginalCodeInputParameters { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在我的关系OnModelCreating中DBContext我做了这样的关系:
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);
Run Code Online (Sandbox Code Playgroud)
现在当我请求Mutants时,OriginalCode为null:
但是一旦我要求OriginalCode如下:
那么OriginalCode突变体的字段将不为空:
是什么原因,我该如何解决?
Iva*_*oev 40
原因在EF Core文档的" 加载相关数据"部分中进行了解释.
第一种行为是因为EF Core目前不支持延迟加载,因此通常您将获得null导航属性,直到您通过急切或显式加载专门加载它们.但是,Eager加载部分包含以下内容:
提示
实体框架核心将自动将导航属性修复为先前加载到上下文实例中的任何其他实体.因此,即使您没有明确包含导航属性的数据,如果之前加载了部分或全部相关实体,仍可能会填充该属性.
这解释了为什么导航属性在第二种情况下不为空.
现在,我不确定你想要解决这两种行为中的哪一种,所以将尝试解决这两种问题.
第一种行为可以通过使用当前可用的方法之一来加载相关数据来"固定",例如急切加载:
var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();
Run Code Online (Sandbox Code Playgroud)
第二种行为是"按设计",无法控制.如果要避免它,请确保DbContext仅使用新的新实例执行单个查询以重试所需的数据.
更新:从v2.1开始,EF Core支持延迟加载.但是默认情况下它没有启用,因此为了使用它,应该标记所有导航属性virtual,安装Microsoft.EntityFrameworkCore.Proxies并通过UseLazyLoadingProxies调用启用它,或者使用不带代理的延迟加载 - 两者都用EF Core文档中的示例进行了解释.
| 归档时间: |
|
| 查看次数: |
12806 次 |
| 最近记录: |