如何防止EF7急切地修復導航屬性?

entity-framework-core

我在Web應用程序中使用EF7時遇到問題,我可以使用它來幫助我。我目前正在使用EF7 RC1。

以下是一些說明我問題的模型。

聯繫

public class Contact
{
    public Guid Id { get; set; }

    public string Desc { get; set; }
    public ContactType ContactType { get; set; }
}

ContactType

public class ContactType
{
    public Guid Id { get; set; }
    public string Desc { get; set; }

    public ICollection<Contact> Contacts { get; set; }
}

這些模型通過Fluent API相關,如下所示:

modelBuilder.Entity<Contact>(entity => {
     // abridged for clarity

     entity
        .HasOne(c => c.ContactType)
        .WithMany(ct => ct.Contacts)
        .IsRequired();                
});

我的需求是能夠從加載了ContactType屬性的數據庫中檢索Contact實體的集合。 EF使這很容易:

using(var context = new MyDbContext()) {
    var contacts = await context
        .Contacts
        .Include(c => c.ContactTypes)
        .Where(/* some search criteria */)
        .ToListAsync();
}

問題在於,在加載Contact實體的ContactType屬性時(由於在查詢中調用.Include()而發生),EF還有助於加載每個ContactType實體的Contacts屬性,從而導致無限的Contacts指向鏈指向在指向聯繫人的ContactTypes和ContactTypes處。我理解為什麼這是默認行為,並且在許多情況下它很有用,但我的需求是將這些實體序列化為JSON並將它們發送到客戶端 - 這是一個只讀的情況。

我希望的行為是EF返回一個Contact集合,其中的Contacts(非null)ContactType屬性的Contacts屬性設置為null。這是EF能做的嗎?有沒有辦法最終得到對像圖我想要手動清空我不想填充的屬性?

我嘗試過的事情:

  • 將.AsNoTracking()附加到EF查詢(似乎不會阻止加載ContactType實體的Contacts屬性)
  • 告訴Json.NET不要序列化無限引用循環(這是在序列化期間避免無限遞歸所必需的,但仍會導致大量額外數據被序列化)

一般承認的答案

你無法避免EF加載ContactType.Contacts集合,因為它實際上沒有加載它,而是用加載的Contact實例填充集合。這就是為什麼使用AsNoTracking沒有效果,因為不是延遲加載和ChangeTracker的問題。

您有三種可能的解決方案:

  1. 使用Json.NET ReferenceLoopHandling = ReferenceLoopHandling.Ignore ,但正如您所說,它將生成大量不必要的數據,因為您將獲得每個ContactType的聯繫人集合
  2. 在ContactType.Contacts上使用[JsonIgnore]屬性,因此序列化程序將忽略它。但它總會忽略它,我不知道你是否需要它在其他情況下
  3. 定義DTO,使用類似Automapper的內容來映射數據(沒有Contacts集合)並將其序列化

我更喜歡第3個選項,因為我不喜歡將域模型對象發送到客戶端,並且它避免向與域無關的域模型添加屬性。


熱門答案

我有同樣的問題實體框架7核心禁用自動加載

我添加AsNoTracking()

IQueryable<ScheduleModel> q = _db.Schedules;
q = q.AsNoTracking();
q = q.Include(x => x.ElementItem);
q = q.Include(x => x.ScheduleHours);

屬性現在不會自動填充。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因