7

私は自分の ASP.NET MVC アプリケーションに何ヶ月も取り組んできました。私が最初に取り組み始めたときは、Entity Framework 4.3 (Code-First w/Migrations) を使用していました。そうしているうちに、MainClient テーブルを更新しようとして、いくつかの問題に遭遇しました。MainClient にはクライアントの基本情報がすべて含まれており、BPClient テーブルと 1:1 の関係があります。BPClient テーブルには、BP モジュールの使用許諾契約に関連するクライアントに関するより具体的な情報が含まれています。どちらも、タブ コントロールの同じページで編集できます。ただし、MainClient オブジェクトの EntityState を EntityState.Modified に変更しようとすると、次の例外が発生し続けました。

System.InvalidOperationException : An object with the same key already exists 
in the ObjectStateManager. The ObjectStateManager cannot track multiple objects 
with the same key.

デバッグ中に、オブジェクトがコントローラ クラスに入って保存されたときに、オブジェクト自体がデタッチされていると見なされていることに気付きました。この問題の回避策として、このブログ投稿この SO の質問で見つかった問題に同様の解決策を適用しました。と呼ばれる MainClient オブジェクトで Edit メソッドが渡されている場合、後でオブジェクトを再アタッチするためのコードは次のようになります (面倒です) client

var newClientObject = new MainClient { ClientID = client.ClientID };
Db.MainClients.Attach(newClientObject);
Db.Entry(newClientObject).CurrentValues.SetValues(client);

var bpClient = new BPClient { ClientID = client.ClientID, BaseClient = newClientObject };
if (client.BPClient != null)
{
    Db.BostonpostClients.Attach(bpClient);
    Db.Entry(bpClient).CurrentValues.SetValues(client.BPClient);
}

Db.SaveChanges()

これは、すべてのテストケースでうまく機能しました。最近まで。

最近、Entity Framework 5 を使用するようにアプリケーションをアップグレードしました (まだ Code-First を使用しています)。しかし、MainClient 編集ページを再度テストしていたときに、かなり不安定な動作を発見しました。一部のフィールドは、編集時に問題なく保存されます。他のものは DB にコミットされることはありません。さらに他のものは問題なく存続しますが、編集中のオブジェクトの唯一の部分である場合に限られます。Controller クラスにある DbContext の全体をデバッグしたところ、ページで行われた変更が Controller クラスに送信されただけでなく、ObjectStateManager に MainClient オブジェクトと BPClient オブジェクトの両方が含まれていることがわかりました。ページに加えられた変更も含まれています。ちなみに、SaveChanges() の後でも、デバッグ中にエラーを 1 つも受け取っていないことをここで言及する必要があります。

コードを元の状態、つまり論理的な方法に戻すことにしました。

Db.Entry<BPClient>(client.BPClient).State = EntityState.Modified;
Db.Entry<MainClient>(client).State = EntityState.Modified;

Db.SaveChanges();

そして今、それは完全にうまく機能します。InvalidOperationException はありません。それで問題なく解決しました。

まだ私を悩ませているのは、以前の修正が機能しなくなり、すべてが不安定になった 5.0 の変更点を突き止めようとしていることです。そのコードが 4.3 では正常に機能したのに、5.0 では機能しなかったのはなぜですか? 5.0 で、そのコードを使用したデータベースへのコミットが非常に不安定になったのはなぜですか?

なぜこれが起こったのか誰か知っていますか?

4

1 に答える 1

0

私は自分でこの問題を抱えていました。IDbSet クラスを使用してデータベース テーブルにデータを入力していましたが、プロパティ仮想 EF5 が遅延読み込みを実行するようにしたときにわかりました (私の仮想プロパティはデータベース内の他のオブジェクトです)。これは、仮想プロパティの新しい主キーを受け取ることを意味します。参照したいオブジェクトに関連付けられた特定の ID がない場合、EF 5 は双方向の関係を作成しようとします。DBContext でマップするプロパティを明示的に EF に指示しない場合、許可されていない同じオブジェクトに 2 つの外部キーが設定されます。お役に立てれば。

于 2012-12-26T15:37:27.643 に答える