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>
解決第二個問題(預先加載相關實體導致導航屬性被填充):
此行為是“設計使然”,無法控制。為避免此問題:
AsNoTracking()
)。 EF Core v2.1 及更高版本更新:
EF Core v2.1 支持延遲加載,但默認情況下未啟用。要啟用它:
virtual
。 Microsoft.EntityFrameworkCore.Proxies
NuGet 包。 UseLazyLoadingProxies()
啟用延遲加載。 通過以上方法,您可以有效地管理 EF Core 中的導航屬性加載,避免空值問題並提高代碼的可預測性。
以上是為什麼 EF Core 導航屬性在明確載入之前為空,以及如何一致地填充它們?的詳細內容。更多資訊請關注PHP中文網其他相關文章!