2017-02-19 21 views
4

我有一个像某些型号的波纹管:EF核心返回null关系,直到直达

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; } 
} 

public class OriginalCode 
{ 
    public long Id { get; set; } 
    ... 

    // Relations 
    public virtual List<Mutant> Mutants { get; set; } 
    public virtual List<OriginalCodeInputParameter> OriginalCodeInputParameters { get; set; } 
} 

,并在DBContextOnModelCreating我做了这样的关系:

 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); 

现在当我要求突变体时,OriginalCode为空:

Null OriginalCode

,但只要我请求OriginalCode就像波纹管:

OriginalCodes

那么突变的OriginalCode领域将是不为空:

Filled Object

是什么原因,我该如何解决?

TG。

回答

10

原因在EF Core文档的Loading Related Data部分中有解释。

第一种行为是因为EF Core目前不支持延迟加载,因此通常您将获得导航属性的null,直到您通过急切或显式加载专门加载它们。然而,预先加载部分包含以下内容:

提示
实体框架的核心将自动修复式导航性能,以先前加载到上下文实例任何其他实体。因此,即使您没有明确包含导航属性的数据,如果先前加载了一些或所有相关实体,该属性仍可能被填充。

这解释了为什么导航属性在第二种情况下不为空。

现在,我不确定你想修复哪两种行为,所以会尝试解决这两个问题。

第一行为可以被“固定”用的用于装载相关的数据的当前可用的方法之一,例如急切装载:

var mutants = db.Mutants.Include(m => m.OriginalCode).ToList(); 

第二行为是“设计”,不能进行控制。如果您想避免它,请确保仅使用新的新实例DbContext执行单个查询以重试所需的数据。

+0

正如你所猜想的,我想控制第一个行为。但仍然有一个很大的问题。你提到的这种方式,我应该明确地解决待填补的关系,是真的吗? – ConductedClever

+0

确实。你必须用几个'Include' /'ThenInclude'方法来指定你想要“包含”的每一个。AFAIK有一些计划将来会自动进行此操作,但现在这是唯一的选择。 –

+0

猜猜怎么样,从来不知道 - 例如在你的EF核心标签中看到一些问题 - [我可以阻止实体框架核心使用部分数据填充我的结果吗?](http://stackoverflow.com/questions/42310340/can-i-stop-entity-framework-core-from-populating-my-result-with-partial-data):) –