これはしばらく私を悩ませていました。私の問題は次のとおりです。私はX xと呼ばれるタイプXのインスタンスを持っています。 Xは、Entity Frameworkによって生成されるエンティティクラスです。エンティティフレームワークに接続されていないエンティティを接続する
私の方法の中では、Webサービスからxを受け取るので、私のオブジェクトコンテキストには添付されていませんが、すでに同じプライマリキーを持つ要素がデータベースに存在することを知っています。メソッドに次のボディを追加し、正常に機能しました。
これまでのところすべて良好でした。しかし、私のObjectContextは、このメソッドによって作成されていない、と突然、このコードは動作を停止し、次のテキストでInvalidOperationException
を投げた:
同じキーを持つオブジェクトが既にObjectStateManagerに存在します。 ObjectStateManagerは、同じキーを持つ複数のオブジェクトを追跡できません。これは、データベースからすべての現在のXオブジェクトを読み取る
objectContext.Xs.ToList();
、それによってObjectStateManagerにそれらを追加しました:
この
は、このコードが実行されたいつか前に、次のコードが実行されたために起こりました。私はこれまでコードによって変更:
objectContext.Xs.ApplyCurrentValues(x);
objectContext.SaveChanges();
これがうまく働いたが、私は再びobjectContext.Xs.ToList();
行を削除した場合、私は次のテキストで別のInvalidOperationException
を得る:
オブジェクトと指定されたオブジェクトのキーと一致するキーがObjectStateManagerに見つかりませんでした。指定されたオブジェクトのキー値が、変更を適用する必要があるオブジェクトのキー値と一致することを確認します。
だから私は反対の問題を抱えています。このメソッドは、ではなく、がObjectStateManagerによって追跡されるため機能しません。私は私のXが既に追跡されているかどうかを決定する任意の信頼性の高い方法を発見していないほか
は、とても現在、私はこのようなコードを追加しました:これは私が使用していることを意味し
try
{
objectContext.Xs.Attach(x);
objectContext.ObjectStateManager.ChangeObjectState(x, EntityState.Modified);
objectContext.SaveChanges();
}
catch(InvalidOperationException)
{
objectContext.Xs.ApplyCurrentValues(x);
}
objectContext.SaveChanges();
例外処理は通常のプログラムフローと同じです(ObjectStateManagerによって要素が既に追跡されていることはほとんどありません)。また別の方法で扱っていたはずの別のInvalidOperationException
を捕捉する可能性があるという問題もあります。
私の質問はそうです。誰もこれのための良い解決策、または少なくともxがObjectStateManagerによって追跡されるかどうかをチェックする適切な方法を知っていますので、try/catchの代わりにそれに基づいてメソッドの1つを選択できますか?
これは実際に私が必要とするものに近いです。私の唯一の問題は、(私は私の元の質問で言及するのを忘れたので)Xはジェネリッククラスの中の型です。だから私が知っているのは、XがEntityObject型であるということです。その情報から、どのパラメータがEntityKeyを構成するかを知る方法はありますか?私はオブジェクトのコンテキストは、キーが一意ではないと不平を言っているので、すでに知っていると思います。 –
[この回答を確認](http://stackoverflow.com/questions/5794902/generic-getbyid-for-complex-pk/5795480#5795480) - エンティティからのキーに関する情報を取得する方法について説明しました。すべてのエンティティにキープロパティが1つしかない場合は、[この簡略化されたバージョン]を使用できます(http://stackoverflow.com/questions/5273416/entity-framework-simple-generic-getbyid-but-has-differents-pk-name/ 5278684#5278684) –
エンティティが 'EntityObject'から派生している場合は、' EntityKey'を直接公開する必要があります。正しく入力していれば、通常はPOCOだけに使用されているこのヘルパーのすべてを使う必要はありません。 –