2010-07-28 51 views
12

我一直堅持這個問題一個多星期了。希望有人能指出我正確的方向。自追蹤實體 - AcceptChanges無法繼續,因爲該對象的鍵值與ObjectStateManager中的另一個對象發生衝突

我從我的模式的簡要說明開始。

資產1 ---> 1個地址* - > 1個區* - > 1區* - > 1國家

包1 - > *資產

使用自跟蹤實體( STE)+ WCF。

步驟:資產清單

  1. 呼叫數據存儲。
  2. 調用數據存儲以獲取軟件包列表。
  3. 用戶選擇一個包併爲其分配一些資產。
  4. 保存包。

在步驟2中,呼叫使用地址的急切加載。

from p in context.Assets.Include("Address.Area.Region.Country") 

這種嘗試調用

context.Packages.ApplyChanges(package) 

的AcceptChanges不能繼續,因爲 對象的鍵值衝突 在 ObjectStateManager另一個對象時的錯誤。在致電 AcceptChanges之前,請確保 鍵值是唯一的。

編輯

周圍窺探後,我發現這是一個STE問題。問題在於,您無法持續保存包含同一實體的多個實例的圖,如here所述。這是我的問題。

如何將實體添加到我的實體 集合中。新實體可能有 相關實體,其中包含與該集合中已有的密鑰相同的 密鑰。 也就是說添加可能包含相同地址,區域,地區或 國家實體的 的新資產。

這裏是我的約束:

  1. 我必須使用導航集合,因爲它影響到UI。
  2. 我無法預取所有將涉及的實體,因爲數據集太大。
  3. 我必須能夠隨時拍攝實體的快照,以便保留歷史記錄並使用它來「撤消」任何更改。

我意識到迭戈乙建議維加可能的解決方案,但這些都不是選項我可以用我的解決方案。有沒有人有任何其他想法?

+0

你有重複鍵,這是不允許的。沒有你的代碼就可以這麼說。 – 2010-07-28 12:37:28

+0

我認爲你需要發佈一個簡單的代碼示例,發生錯誤。幾乎不可能說出任何內容,而不是您的帖子中提供的信息中有重複的密鑰。 – 2010-07-30 13:52:22

回答

8

僅供參考,我寫了一個博客帖子有一些額外的建議,我已經在EF論壇迴應。 Here是博客文章。

+0

這是一個非常有用的博客。正是我需要的。圖迭代器值得研究。 – 2010-10-07 00:46:52

+0

如果EF將有問題的對象/鍵的名稱添加爲長錯誤消息,那將會很好。對於維護現有應用程序的人員,代碼中的小改動可能會導致無意中創建一個新的對象圖形。精確的錯誤消息是無價的。感謝您的博客。 – SRO 2013-09-23 16:56:01

8

你有沒有考慮剛剛放棄對ORM-S和回到正常訪問,如果你知道我的意思:-)

不是在開玩笑 - 你的時間與一個單一的問題搏鬥一樣,一個(這聽起來像ORM錯誤比其他任何東西都大)你可能已經推出了自己的5-10個函數來執行普通的sproc調用和更簡單的數據類型轉換,然後你又回到了完全控制的狀態,而不是被圖書館卡住以另一個像5年穩定。

特別是因爲你似乎有非常乾淨的模式 - 這意味着很簡單的查詢和直接更新。

+0

我真的很喜歡這個想法,但不幸的是我沒有那麼靈活。我將在未來的項目設計中考慮到這一點。 – 2010-08-05 13:41:28

+0

我剛剛拆除了一個,就像2個月前一樣,所以它是從個人經驗:-)嵌入只是一個簡單的類來創建/清理連接和卓越的讀者(它的DataReader 99%的時間總之)和一個靜態類來構建In /使用短功能(6-8種類型)和可空結果(再次使用6-8種類型)可以輸出參數(所以我可以輸入較少的:-)哦,還有一個智能模板類可以自動處理讀寫器和連接。什麼是解脫 - 更不用說性能提升了:-) – ZXX 2010-08-06 06:18:10

+0

問題在於管理網站每個功能的「5-10個功能」。 ORM比預先節省的時間多。每次添加/更改屬性時,無需在5個位置進行更改 – 2015-08-13 13:09:35

3

我遇到了同樣的問題,最後想出了一個解決方案。基本的想法是阻止某些導航類類型附加到ObjectContext。 這是我做的:

  1. 修改context.tt模板使SelfTrackingEntitiesContextExtensions類部分。
  2. 將2個ApplyChanges函數複製到新創建的Custom.Context.Extension.cs中,並將它們重命名爲CustomApplyChanges。每次都會有一個附加參數爲類型的陣列

公共靜態無效 CustomApplyChanges(這 ObjectContext的上下文中,串 entitySetName,TEntity實體,類型[] excludeTypes)其中TEntity: IObjectWithChangeTracker

  1. 向for循環添加一個條件以排除excludeTypes數組中包含的任何類類型。

區域拉手初始實體狀態

的foreach(IObjectWithChangeTracker changedEntity在 entityIndex.AllEntities.Where(X => x.ChangeTracker.State == ObjectState.Deleted & & ! excludeTypes.Contains(x.GetType()))) {HandleDeletedEntity(context, entityIndex,allRelationships, changedEntity); }

的foreach(IObjectWithChangeTracker changedEntity在 entityIndex.AllEntities.Where(X => x.ChangeTracker.State!= ObjectState.Deleted & & !excludeTypes.Contains(X。GetType()))) {HandleEntity(context,entityIndex, allRelationships,changedEntity); }

endregion

  • 用法
  • 類型[] excludeTypes = {typeof運算(資產)的typeof(地址)的typeof(區域)};

    rep.Entities.CustomApplyChanges(entity,excludeTypes); var changedEntry = rep.Context.ObjectStateManager.GetObjectStateEntries>(System.Data.EntityState.Added | System.Data.EntityState.Modified | System.Data.EntityState.Deleted);如果(excludeTypes.Any(c => c == e.Entity.GetType())) { rep.Context.Detach(e.Entity); //分離改變對象 }}

    +0

    我已經使用此方法取得了巨大成功。感謝你的分享。 – mortware 2011-07-18 08:07:41

    +0

    我有一個實體與另一個實體有2個關聯,並在原始文章中獲取錯誤消息。我已經實現了這一點。看起來,這段代碼只是將Exclude類型分開,所以它們根本不會被保存。我沒有得到這個錯誤,但是關聯(設置了Ids的地方)沒有得到保存?不知道這將如何工作?我錯過了什麼嗎? – 2013-05-11 09:53:49

    1

    我解決了這個問題,方法是在保存之前設置重置外鍵Ids,這需要將Navigation值設置爲null。

    ...是這樣的:

    var countryToId = address.CountryToId; 
    var countryFromId = address.CountryFromId; 
    documentAddress.CountryTo = null; 
    documentAddress.CountryFrom = null; 
    documentAddress.CountryToId = countryToId; 
    documentAddress.CountryFromId = countryFromId; 
    
    0

    因爲我刪除實體的記錄,補種,然後再填充新的數據實體,我得到這個錯誤。

    由於在此實體上啓用了自我跟蹤功能,因此不允許使用相同的密鑰添加記錄,即使具有該密鑰的記錄之前已被刪除。

    因爲我並不需要在這種情況下自我跟蹤,我禁用它:

    dbcontext.entity.MergeOption = System.Data.Objects.MergeOption.NoTracking; 
    
    相關問題