7

私は数か月前からASP.NET MVCアプリケーションを開発してきました。私が最初に作業を開始したとき、私はEntity Framework 4.3(Code-First w/Migrations)を使用していました。私が行っている間に、私はMainClientテーブルの更新をしようとするといくつかの問題に遭遇しました。 MainClientには、クライアントのすべての基本情報が含まれており、BPクライアントテーブルと1対1の関係にあります。このテーブルには、BPモジュールの使用許諾契約に関するクライアントに関するより具体的な情報が含まれています。どちらもタブコントロールの同じページで編集できます。しかし、私はEntityState.ModifiedされることにMainClientオブジェクトのEntityStateを変更しようとすると、次の例外を得ることに保た:Entity Framework 4.3 vs. 5.0差分の更新

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

それは私のコントローラクラスに入ったときにオブジェクト自体が独立したと考えられていたことをデバッグ中に私は気づきました救われるべきです。この問題の回避策として、this blog postthis SO questionにある問題に同様のソリューションを適用しました。 clientと呼ばれるここでオブジェクトを再付着させるためのコードは、編集方法がMainClientオブジェクトに渡されている与えられた、(私が知っている、乱雑)後で見てみましょう:

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オブジェクトの両方が含まれていることがわかりましたそれはページ上で行われた変更と同様にところで、ここでは、デバッグ中にエラーが1つも発生せず、SaveChanges()の後でもエラーは表示されません。

私はそれを行うための論理的な方法と言うことです、それはもともとあったものにコードを試してみて、元に戻すことにしました:

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では、そのコードをデータベースにコミットさせて何が変わったのですか?

これはなぜ起こったのでしょうか?

+0

お手数ですが、エンティティフレームワーク5 Enums and EF 4.3からのソリューションの移動http://thedatafarm.com/blog/data-access/video-entity-framework-5-enums-and-moving-solution-from-ef-4-3/ – Aru

答えて

0

私はこの問題を自分で持っていました。私はIDbSetクラスを使用してデータベーステーブルを作成していましたが、私が見つけたのは、EF5がレイジーロードを実行するときのプロパティ(データベースの他のオブジェクトがある仮想プロパティ)でした。つまり、私は仮想プロパティの新しいプライマリキーを受け取ります。私が参照したいオブジェクトに関連付けられた特定のIDを持っていなければ、EF 5は双方向の関係を作ろうとします。 DBContextにマップするプロパティを特にEFに指示しない場合、許可されていない2つの外部キーを同じオブジェクトに設定します。お役に立てれば。

+0

私の質問に答えるために。私はこれがここのケースだとは思わない。私はすでに、MainClientとBPClientの間に双方向の関係(仮想プロパティとIDの両方)として1:1を設定しています。私はちょうどすべてのコードが突然動作しなくなった理由を理解しようとしています。 – IronMan84

+0

virutalプロパティのみを使用すると遅延読み込みが発生しますが、プロパティ間のdbcontextで同じマップが実行されますか? – Robert

+0

私はFLuent APIではなくData Annotationを使用しています。マッピングは、DbContextではなくオブジェクト自体にのみ行われます。このような方法でコードに影響を与える遅延ロードに関する4.3と5.0の間に何かが発生しましたか? – IronMan84

関連する問題