2012-02-24 9 views
0

まず、Entity Frameworkコードとマージするのに苦労しています。 私は汎用リポジトリを持つMVCコントローラを持っています。ビューモデルは、最大掲示し、私は型にEFを約Entity Framework 4は、データをトラッキング対象エンティティにマージする

var converted = AutoMapper.Mapper.Map<RoutineViewModel, Routine>(result); 
    _routineRepository.Update(converted); 

私が持っているリポジトリに知っていることを変換します:

/* 
      Routines.Attach(item); 
      ChangeTracker.Entries<Routine>().Single(x => x.Entity.Id == item.Id).State = EntityState.Modified;*/ 
      var match = Routines.Single(x => x.Id == item.Id); 
      var entity = Entry(match); 

      entity.CurrentValues.SetValues(item); 

それはに関するエラーを投げていたので、私は最初のビットをコメントアウトしますすでにこのようなチェックにもかかわらず、実体を追跡:

if (ChangeTracker.Entries<Routine>().Count(x => x.Entity.Id == item.Id) != 0) 

が返さ偽

私が抱えている問題は、ルーチンオブジェクトにステップのICollectionプロパティがあることです。ポコのものと一致するトラッキングされたエンティティの値を設定すると、ICollectionの変更は伝播しません。このサイトの周りを見ると、いくつかの厄介な再帰呼び出しがあるように見えます。これは本当にどのように動作するのですか、何かが欠けていますか?

ここではソースオブジェクト(untracked)があり、トラックオブジェクトにすべての情報をコピーしています。

私はオブジェクトを最初に取得し、そのプロパティを更新することはリポジトリの外で行うべきだとはっきりとは思いません。これは、ドメイン境界を越えてデータモデルを渡すように強制するだけではなく、等価なSQLのようなステートメント(update x、y where id = 1)、to(tempテーブルへの挿入、id = 1、reachテーブル更新テーブルx = tempx id = 1の各行について

編集 - したがって、問題はsetValuesが再帰呼び出しではないことにあります。ルーチンオブジェクトには2つの単純なプロパティ(idとname)と1つの複合(ICollection)があります。項目の名前が変更され、いくつかのステップが変更された場合、setValuesは名前の変更を取り上げますが、子には適用されません。これを行うには他の方法がありますか?私はこの機能をロールバックしなければならないと私には少しばかげているようです。

答えて

0

あなたのエンティティを作成し、プロパティを設定してDBにアタッチしていることがわかります。これは、EFで間違った方法です。

DBに既に存在していても追跡されていないオブジェクトをアタッチする場合は、アタッチを使用できますが、アタッチコールが記録された後に行われた変更のみがDBにコミットされます。アタッチを使用する場合は、そのメソッドを呼び出した後に変更を加えてください。

さらに、EFでは、オブジェクトグラフに現在存在しないオブジェクトのみを添付することができます。したがって、同じオブジェクトを2回(または同じキーで1つ)アタッチしようとすると、表示されているようなエラーが表示されます。

+0

こんにちはルーク、情報をありがとうが、私はリポジトリからエンティティを取得する必要はありません、それを変更し、その 'EFだけでコミットする必要があります。私の前提は、SetValuesは基本的にすべてのプロパティの再帰比較を行い、一致しなかったトラッキング対象エンティティにanyを割り当てるというものでした。エラーをスローするコメントアウトされたコードについては、オブジェクトはアタッチされず(メインコードブロックの下にある変更トラッカー呼び出しを参照)、どちらもエンティティが最初から完全に作成されたため、発生する。 – Dylan

+0

新しいエンティティを作成する場合、通常の方法はRoutines.Add(myNewRoutine)を使用することです。attachは、DBには既に存在していてオブジェクトグラフにまだロードされていないオブジェクトを再接続するためのものです。 –

+0

こんにちはルーク、 私は意図的に少しのコードを残しましたが、私はRoutines.Add(item)を呼び出すinsertメソッドを持っています。問題はありません。これは、更新シナリオを処理することです – Dylan

関連する問題