[英]Attach same object to different contexts in Entity Framework 6
從我讀到的所有內容到現在,不應該將相同的對象附加到不同的dbcontexts(我可以找到的所有示例和問題都在這種情況下顯示異常)。 現在,當我使用EF6進行測試時,它允許我將相同的對象附加到不同的上下文(來自不同的線程); 我甚至能夠從一個線程更改對象並將其與另一個線程一起保存。 這不一定是壞事(除了事實我必須確保我一直鎖定,因為沒有拋出異常),只是我想了解發生了什么。
有人知道這是否真的是EF6中的“新功能”?
一些代碼在這里。 從幾個不同的線程調用它沒有異常,如果我在保存之前從另一個線程更改對象,它將采用最后的值:
using (var db = new TestContext())
{
db.Users.Attach(_cachedUser);
MessageBox.Show("attached"); //I use this to pause the thread as long as I want
_cachedUser.UserCode = tbCode.Text;
_cachedUser.UserDesc = tbDesc.Text;
MessageBox.Show("ready to save"); //pause again
db.SaveChanges();
}
編輯收到答案為什么會發生這種情況后,我還發現了如何檢查對象是否是代理: http : //msdn.microsoft.com/en-us/library/vstudio/ee835846(v = vs.100)。 ASPX
public static bool IsProxy(object type)
{
return type != null && ObjectContext.GetObjectType(type.GetType()) != type.GetType();
}
工作得很好。
這是可能的,因為實體框架引入了代碼優先的樣式,因為您只能使用POCO執行此操作。
cachedUser
是一個普通的C#類。 它沒有關於它附加的上下文的任何信息。 此外,新的上下文實例不了解另一個上下文的更改跟蹤器。 所以沒有辦法檢查POCO是否附加到任何地方的上下文。
當cachedUser
不是POCO而是代理對象時,這會發生變化。 (代理對象是EF在運行中創建的對象。它繼承自實體類,它包含啟用延遲加載和促進更改跟蹤的代碼和狀態)。 當您嘗試將代理對象附加到第二個上下文時,您將收到異常:
IEntityChangeTracker的多個實例不能引用實體對象。
這就是為什么在許多情況下,建議創建代理而不是POCO。 您可以使用db.Users.Create()
代替new User()
來創建代理。
什么時候創建代理,這是否可行以及何時EF物化代理是一個超出此問題范圍的主題。 有關這方面的更多信息,請點擊此處
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.