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 のままになります。
解決策:
この動作を解決するには 2 つの方法があります:
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コア関係がnullされるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。