2016-07-05 71 views
0

考慮以下(非常簡單的)實體:實體框架懶加載不正確實體

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class Answer 
{ 
    public int Id { get;set; } 
    public virtual User User { get; set; } 
    public string Text { get;set } 
} 

public class TeamMember 
{ 
    public int Id { get;set; } 
    public virtual User User { get; set; } 
    public string Role { get; set; } 
} 

在我的映射我可以設置用戶罰款,但只要將下面的代碼執行(持久保存任何更改之前,在DB)

if (teamMembers.Select(x => x.User).Contains(currentUser))

其中teamMembers是teamMembers的列表,currentUser是從數據庫加載的用戶實體,然後回答的用戶屬性設置爲從數據庫中前值。 我的理解是,因爲我沒有訪問答案的用戶屬性之前它並沒有被從數據庫加載的是,這是發生了什麼(它一直延遲加載?)。

,我可以通過讀取用戶之前,即使是在映射器設置它解決它,但我不能理解的是,爲什麼當我訪問TeamMember的用戶屬性加載答案的用戶屬性和設置?這是預期的行爲,因爲兩個實體都與同一個用戶相關聯(即在數據庫中它們具有與外鍵相同的User_Id),並且在爲TeamMembers加載時,EF試圖聰明並填充引用它的其他實體, t已經加載了嗎?

回答

0

的實體不存儲/由具有對它們的引用,但保存自己收藏各自的元素緩存。

一旦加載通過teamMembers參考用戶,它加載中...時期。當你從另一個元素/對象去引用它時,當它在內存中已經有了這個對象時,它將會很難再去加載它。

這是全部設計,它是有道理的...如果,例如,你想同時保存所有這些對象,它會首先創建用戶,獲取身份/密鑰,然後保存其他對象使用生成的密鑰引用它。

裁判:https://msdn.microsoft.com/en-us/data/hh949853.aspx#3

」 ...的ObjectContext中會檢查是否使用相同的密鑰的實體 已經被加載到其ObjectStateManager如果與 相同的密鑰的實體已經存在EF會。它包括在 查詢的結果。雖然EF依然會發出對數據庫查詢, 這種行爲可以繞過很多 多次物化實體的成本。」

+0

感謝您的答覆,但它並沒有完全回答我的問題(也許是不夠明確)。假設我有兩個用戶,User1 {}和User2 {}。任何人都可以解釋爲什麼當我從'User1 {}'設置'answer.User'的值爲'User2 {}',然後不保存運行一個選擇(例如'teamMembers.Select(x => x .User).Contains(currentUser)')在我的teamMembers集合中,然後將我的答案的User屬性重置回User1 {}'? – msokrates

+0

用戶2是否已經被保存到數據庫中,還是隻在該內存中? –

+0

我將User.User設置爲User2(我從數據庫中檢索),但不保存此更改,但如果這就是您的意思。 – msokrates