2011-07-12 42 views
3

我的實體導航屬性引起我深深的克隆失敗,出現錯誤:如何深入克隆實體並避免導航屬性導致的錯誤?

"An object with the same key already exists in the ObjectStateManager"

背景:

用戶希望能夠克隆父記錄及其所有相關子記錄。我使用這個簡單的技術能夠單獨克隆父實體(沒有錯誤):

_context.Detach(currentParentEntity); 
_context.AddToParentEntities(currentParentEntity); 
_context.SaveChanges(); 

我發現,解決方案和其他工作淺克隆技術(從diamandiev)here

由於我真正需要的是深層副本,我嘗試實施的序列化克隆技術顯示爲here,herehere。我的調用代碼看起來是這樣的:

ParentEntity clonedParentEntity = (ParentEntity)DeepClone(currentParentEntity); 
_context.Detach(currentParentEntity); 
clonedParentEntity.EntityKey = null; 
_context.AddToParentEntities(clonedParentEntity); 
_context.SaveChanges(); 

此代碼只克隆沒有子實體currentParentEntity(在導航屬性引用)時的作品。如果存在子實體,我會得到「具有相同密鑰的對象已經存在」的錯誤。爲什麼? 如何深入克隆父實體及其關聯的子實體,然後保存克隆的記錄沒有任何錯誤?

在此先感謝。

編輯:完整接受的答案請閱讀Ladislav Mrnka的回答加上評論

回答

2

如果你真的使用了序列化,你克隆了父實體和子實體 - 這不是你的問題。您的問題是撥打Detach,因爲它只會刪除您分離的單個實體(而不是其子代)。所以這個錯誤是由添加具有已經被上下文跟蹤的相同密鑰的孩子造成的。

+0

這很有道理。現在我可以使用一些幫助來分離子實體,然後保存克隆的記錄而不會出錯。我可以在哪裏找到一個好的代碼示例的任何建議?我發現的樣本不完整。 – DeveloperDan

+0

可能沒有這樣的例子。最簡單的方法是創建克隆並將其添加到上下文的新實例。 –

+1

使用新的上下文工作。謝謝!使用新的上下文調用SaveChanges後,我重新查詢原始上下文以顯示克隆的記錄。我必須確定在新的上下文中調用Dispose,或者在修改新記錄時出現錯誤:「兩個對象之間的關係無法定義,因爲它們連接到不同的ObjectContext對象。」即使我在Using語句中聲明它,新的上下文仍需要Context.Dispose。問題解決了。 StackOverflow岩石! – DeveloperDan