我是新來的實體框架,並試圖學習如何使用Code First從數據庫加載實體。如何防止實體框架中相關實體的循環加載代碼優先
我的模型包含一個用戶:
public class User
{
public int UserID { get; set; }
[Required]
public string Name { get; set; }
// Navigation Properties
public virtual ICollection<AuditEntry> AuditEntries { get; set; }
}
每個用戶都可以有一組審計條目,每個條目都包含一個簡單的信息:
public class AuditEntry
{
public int AuditEntryID { get; set; }
[Required]
public string Message { get; set; }
// Navigation Properties
public int UserID { get; set; }
public virtual User User { get; set; }
}
我有一個的DbContext剛剛暴露出兩個表格:
public DbSet<User> Users { get; set; }
public DbSet<AuditEntry> AuditEntries { get; set; }
我想要做的是加載一個包含混亂的AuditEntry對象列表年齡和包含UserID和Name屬性的相關User對象。
List<AuditEntry> auditEntries = db.AuditEntries.ToList();
因爲我有我的導航屬性標記爲虛,我還沒有禁用延遲加載,我得到一個無限深對象圖(每個AuditEntry有一個用戶對象,它包含了AuditEntries的列表,每個其中包含一個用戶對象,其中包含一個審覈條目列表等)
如果我然後想要序列化對象(例如作爲結果發送到Web API),這是沒有用的。我試過關閉延遲加載(通過從我的導航屬性中刪除模型中的虛擬關鍵字,或者通過將this.Configuration.LazyLoadingEnabled = false;添加到我的DBContext中)。正如預期的那樣,這將導致User設置爲null的AuditEntry對象的平面列表。
懶加載的時候,我一直在努力,渴望加載用戶像這樣:
var auditentries = db.AuditEntries.Include(a => a.User);
但像以前那樣會導致同一個深/循環的結果。
如何在沒有將反向引用/導航屬性加載回原始對象並創建循環的情況下加載一個深度級別(例如,包括用戶的ID和名稱)?
'Include'應該做到這一點。你確定'User.AuditEntries'不是延遲加載嗎? –
如果在上下文處理後序列化對象會怎麼樣? –
我認爲最初但我不認爲它是延遲加載 - 從我的所有導航屬性中刪除虛擬關鍵字並明確禁用延遲加載似乎沒有幫助。 我認爲這是因爲我的導航屬性是雙向的,例如,用戶具有一個AuditEntries列表,而AuditEntries定義它所屬的用戶。我想查詢AuditEntries幷包含用戶信息,但我不希望每個頂級AuditEntry對象都包含該用戶的所有其他AuditEntry的列表。 這很棘手,因爲我正在努力描述發生了什麼! –