這是我第一篇文章,所以我希望一切都很好。EF STE和自參考表問題
這裏是我的問題: 我有一個表在我的數據庫稱爲UserTypes。它有:
- ID;
- IsPrivate;
- Parent_ID;
有關的是第一個和第三個。 我有另一個表叫UserTypes_T其中有不同類型的信息,即語言特定。這些字段是:
- Language_ID;
- UserType_ID;
- 名稱;
我試圖做到的,是從UserTypes表加載整個層次結構,並顯示在一個TreeView(這是不相關的現在)。然後,通過選擇一些用戶類型,我可以在單獨的編輯框(名稱)和組合框(父)中編輯它們。
一切工作正常,直到我試圖堅持數據庫中的更改。 EF爲我生成兩個實體類爲這些表:
用戶類型的類有:
- ID;
- IsPrivate;
- Parent_ID;
- 自引用的導航屬性(0..1);
- 子元素的導航屬性;
- UserTypes_T表的另一個導航屬性(1 .. *);
用於翻譯的信息的類有:
- UserType_ID;
- Language_ID;
- 名稱;
- UserTypes表的導航屬性(* .. 1);
- 語言表的導航屬性(* .. 1);
我得到我需要使用數據:
return context.UserTypes.Include("UserTypes_T").Where(ut => ut.IsPrivate==false).ToList();
在我的WCF Web服務。我可以添加沒有問題的新用戶類型,但是當我嘗試更新舊用戶時,會發生一些奇怪的事情。
如果我更新根元素(Parent_ID == null),一切正常! 如果我更新的元素,其中PARENT_ID = NULL我收到以下錯誤:我找遍了互聯網
AcceptChanges cannot continue because the object’s key values conflict with another object in the ObjectStateManager.
和Diego B Vega(還有更多)閱讀博客文章,但我的問題是不同的。當我更改父級用戶類型時,實際上我更改了Parent_ID屬性,而不是導航屬性。我總是嘗試使用ID而不是生成的導航屬性來避免問題。
我做了一個小調查,想看看什麼是對象圖,我得到,看到,有很多重複的實體:
根元素有它的子元素的列表。每個子元素都具有對根或其父代的反向引用等等。你可以想象。由於我沒有使用這些導航屬性,因爲我使用ID來獲取/設置我需要的數據,所以我將它們從模型中刪除。具體我刪除了點和 用戶類型實體類。然後我有一個對象圖,每個元素只有一次。我嘗試了一個新的更新,但我有同樣的問題:
根元素更新正常,但有一些父母的元素拋出了相同的異常。
我看到我在UserTypes_T實體類中有一個導航屬性,指向一個用戶類型,所以我也刪除了它。然後這個錯誤消失了。對象圖中的所有項目都是唯一的。但問題仍然是 - 我可以毫無問題更新我的根元素,但是當試圖更新子(無例外),我在生成Model.Context.Extensions類空引用異常:
if (!context.ObjectStateManager.TryGetObjectStateEntry(entityInSet.Item2, out entry))
{
context.AddObject(entityInSet.Item1, entityInSet.Item2);//here!
}
我試圖只更新名稱(這在UserTypes_T),但錯誤是相同的。
我出來的想法,我一直試圖解決這個問題現在8個小時,所以我會很感激,如果有人給我的想法或分享他們的經驗。
PS:
我成功更新子對象是使用下面的代碼來獲取數據的唯一方法:
var userTypes = argoContext.UserTypes.Include("UserTypes_T").Where(ut => ut.IsPrivate==false).ToList();
foreach (UserType ut in userTypes)
{
ut.UserType1 = null;
ut.UserTypes1 = null;
}
return userTypes;
其中UserType1是導航性能,指向父用戶類型和UserTypes1是導航屬性,其中包含子元素的列表。這裏的問題是EF「修正」了對象並將Parent_ID更改爲null。如果我再次設置它,EF也會設置UserTypes1 ...也許有一種方法可以阻止此行爲?