首頁 >後端開發 >C++ >為什麼 EF Core 導航屬性在明確載入之前為空,以及如何一致地填充它們?

為什麼 EF Core 導航屬性在明確載入之前為空,以及如何一致地填充它們?

Barbara Streisand
Barbara Streisand原創
2025-01-24 22:25:09764瀏覽

Why are EF Core navigation properties null until explicitly loaded, and how can I consistently populate them?

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>

在 DbContext 的 OnModelCreating 方法中定義關係:

<code class="language-csharp">modelBuilder.Entity<Mutant>()
    .HasOne(m => m.OriginalCode)
    .WithMany(oc => oc.Mutants)
    .HasForeignKey(m => m.OriginalCodeId)
    .OnDelete(DeleteBehavior.Restrict);</code>

當查詢 Mutant 時,OriginalCode 屬性最初為空。但是,如果在查詢 Mutant 之前先查詢 OriginalCode,則 OriginalCode 屬性會被填充。

原因分析

EF Core 文檔的“加載相關數據”部分對此行為進行了說明:

Entity Framework Core 目前不支持延遲加載,因此通常情況下,在您通過預加載或顯式加載它們之前,導航屬性將為空。

然而,“預加載”部分包含以下內容:

提示 Entity Framework Core 將自動修復任何先前已加載到上下文實例中的其他實體的導航屬性。因此,即使您沒有顯式包含導航屬性的數據,如果先前已加載部分或全部相關實體,該屬性仍可能被填充。

解決方案

解決第一個問題(導航屬性為空):

使用可用的加載相關數據的方法,例如預加載:

<code class="language-csharp">var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();</code>

解決第二個問題(預先加載相關實體導致導航屬性被填充):

此行為是“設計使然”,無法控制。為避免此問題:

  • 為每個查詢使用新的 DbContext 實例。
  • 使用無跟踪查詢 (AsNoTracking())。

EF Core v2.1 及更高版本更新:

EF Core v2.1 支持延遲加載,但默認情況下未啟用。要啟用它:

  • 將所有導航屬性標記為 virtual
  • 安裝 Microsoft.EntityFrameworkCore.Proxies NuGet 包。
  • 使用 UseLazyLoadingProxies() 啟用延遲加載。

通過以上方法,您可以有效地管理 EF Core 中的導航屬性加載,避免空值問題並提高代碼的可預測性。

以上是為什麼 EF Core 導航屬性在明確載入之前為空,以及如何一致地填充它們?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn