2017-02-19 23 views
4

у меня есть некоторые модели, как те ниже:EF Ядро возвращает нулевые отношения недо прямого доступа

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

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

теперь, когда я запрашиваю для Mutants, значение OriginalCode равно null:

Null OriginalCode

, но как только я прошу для OriginalCode с как ниже:

OriginalCodes

то OriginalCode поле мутантов будет не нулевым:

Filled Object

В чем причина и как я могу это исправить?

TG.

ответ

10

Причина объясняется в разделе Loading Related Data документации EF Core.

Первое поведение связано с тем, что в настоящее время EF Core не поддерживает ленивую загрузку, поэтому обычно вы получаете null для свойств навигации, пока вы не загрузите их с помощью явной или явной загрузки. Тем не менее, жадная загрузка раздел содержит следующее:

Совета
Entity Framework ядро ​​будет автоматически фиксировать вверх свойство навигации к любым другим лицам, которые ранее были загружены в экземпляр контекста. Поэтому, даже если вы явно не включаете данные для свойства навигации, свойство все равно может быть заполнено, если ранее были загружены некоторые или все связанные объекты.

, который объясняет, почему свойство навигации не является нулевым во втором случае.

Теперь я не уверен, какое из двух поведений вы хотите исправить, поэтому постарайтесь решить оба вопроса.

Первое поведение может быть «фиксированной» с помощью одного из имеющихся в настоящее время методы для данных, связанных с загрузкой, например, нетерпеливого загрузка:

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

Второе поведение «дизайн» и не может управляться. Если вы хотите избежать этого, обязательно используйте новый новый экземпляр DbContext только для выполнения одного запроса, чтобы повторить необходимые данные.

+0

Как вы могли догадаться, я хочу контролировать первое поведение. Но есть еще большой вопрос. Таким образом, вы упомянули, я должен прямо рассмотреть отношения, которые нужно заполнить, правда? – ConductedClever

+0

Действительно. Вы должны указать каждый из них, который вы хотите включить, используя несколько методов 'Include' /' ThenInclude'.AFAIK есть некоторые планы сделать это автоматически в будущем, но на данный момент это единственный вариант. –

+0

Как насчет угадывания, никто никогда не знает - например, посмотрите несколько вопросов перед вашим в теге EF Core - [Могу ли я остановить Entity Framework Core от заполнения моего результата частичными данными?] (Http://stackoverflow.com/questions/42310340/can-i-stop-entity-framework-core-from-populating-my-result-with-partial-data) :) –