これは私の最初の投稿です。すべてがうまくいくことを願っています。
ここに私の問題があります: データベースにUserTypesというテーブルがあります。それは持っています:
- ID;
- IsPrivate;
- 親_ID;
該当するのは1枚目と3枚目です。UserTypes_Tという別のテーブルがあります。これには、言語固有のさまざまなタイプの情報が含まれています。フィールドは次のとおりです。
- 言語_ID;
- UserType_ID;
- 名前;
私が達成しようとしているのは、UserTypesテーブルから階層全体を読み込み、それを TreeView に表示することです (これは今のところ関係ありません)。次に、いくつかのユーザー タイプを選択して、個別の編集ボックス (名前) とコンボ ボックス (親) で編集できます。
データベースの変更を永続化しようとするまで、すべてが正常に機能します。EF は、これらのテーブルに対して 2 つのエンティティ クラスを生成してくれました。
ユーザータイプのクラスには次のものがあります。
- ID;
- IsPrivate;
- 親_ID;
- 自己参照のナビゲーション プロパティ (0..1)。
- 子要素のナビゲーション プロパティ。
- UserTypes_T テーブルの別のナビゲーション プロパティ (1..*)。
翻訳された情報のクラスには次のものがあります。
- UserType_ID;
- 言語_ID;
- 名前;
- UserTypes テーブルへのナビゲーション プロパティ (*..1)。
- Languages テーブルへのナビゲーション プロパティ (*..1)。
以下を使用して必要なデータを取得します。
return context.UserTypes.Include("UserTypes_T").Where(ut => ut.IsPrivate==false).ToList();
私のWCF Webサービスで。問題なく新しいユーザー タイプを追加できますが、古いユーザー タイプを更新しようとすると、奇妙なことが起こります。
ルート要素 (Parent_ID==null) を更新すると、すべてが機能します。Parent_ID!=null の要素を更新すると、次のエラーが発生します。
オブジェクトのキー値が ObjectStateManager 内の別のオブジェクトと競合するため、AcceptChanges を続行できません。
私はインターネット全体を検索し、Diego B Vega (およびその他多数) のブログ投稿を読みましたが、私の問題は異なります。親ユーザー タイプを変更すると、実際にはナビゲーション プロパティではなく、Parent_ID プロパティが変更されます。問題を回避するために、生成されたナビゲーション プロパティではなく、常に ID を使用するようにしています。
私は少し調査を行い、取得したオブジェクトグラフが何であるかを確認しようとしましたが、重複するエンティティがたくさんあることがわかりました:
ルート要素には、その子要素のリストがありました。各子要素には、ルートまたはその親などへの後方参照がありました。想像できるでしょう。ID を使用して必要なデータを取得/設定したため、これらのナビゲーション プロパティを使用していなかったので、それらをモデルから削除しました。具体的には、 UserTypesエンティティ クラスからポイント4と5を削除しました。次に、各要素を 1 回だけ含むオブジェクト グラフを作成しました。新しいアップデートを試しましたが、同じ問題がありました:
ルート要素は正常に更新されましたが、いくつかの親を持つ要素が同じ例外をスローしました。
UserTypes_Tエンティティ クラスに、ユーザー タイプを指すナビゲーション プロパティがあることがわかったので、それも削除しました。その後、このエラーは消えました。オブジェクト グラフ内のすべてのアイテムは一意でした。しかし、問題は残っていました - ルート要素を問題なく更新できましたが、(除外なしで) 子を更新しようとすると、生成された Model.Context.Extensions クラスで null 参照例外が発生しました:
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を設定します...この動作を停止する方法はありますか?