EF Core在直接訪問之前返回空關係

entity-framework-core

我有一些類似下面的模型:

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

OnModelCreatingDBContext我創建了以下關係:

        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字段將不為null:

填充對象

是什麼原因,我該如何解決?

一般承認的答案

原因在EF Core文檔的“ 加載相關數據”部分中進行了解釋。

第一種行為是因為EF Core目前不支持延遲加載,因此通常您將獲得導航屬性的null ,直到您通過急切或顯式加載專門加載它們。但是, Eager加載部分包含以下內容:

小費
實體框架核心將自動將導航屬性修復為先前加載到上下文實例中的任何其他實體。因此,即使您沒有明確包含導航屬性的數據,如果之前加載了部分或全部相關實體,仍可能會填充該屬性。

這解釋了為什麼導航屬性在第二種情況下不為空。

現在,我不確定你想要解決這兩種行為中的哪一種,所以將嘗試解決這兩個問題。

可以通過使用當前可用的方法之一來加載相關數據來“修復”第一個行為,例如預先加載:

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

第二種行為是“按設計”,無法控制。如果要避免它,請確保使用全新的DbContext實例來執行單個查詢以重試所需的數據。

更新:從v2.1開始,EF Core支持延遲加載 。但是默認情況下它沒有啟用,所以為了利用它,應該將所有導航屬性標記為virtual ,安裝Microsoft.EntityFrameworkCore.Proxies並通過UseLazyLoadingProxies調用啟用它,或者使用不帶代理的延遲加載 - 兩者都用EF Core中的示例解釋文檔。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow