2012-03-08 18 views
1

以下のモデルがあります。Entity Frameworkの多対多リレーションシップを削除するとエラーが発生します

enter image description here

私はActivityTypeを関連付けられた指定でProductTypeを削除しようとしています。しかし、私はジェネリックメソッドを介して削除を扇動しようとすると、その関係を削除するだけでなく、それもProductTypeを削除しようとしている!

"ストアの更新、挿入、または削除のステートメントが予期しない行数(0)に影響を与えました。エンティティがロードされてからエンティティが変更または削除された可能性があります。 ObjectStateManagerのエントリ。

下記のコードを削除してください。

public void DeleteEntityAndSaveChanges<T, T1>(T entity, List<T1> subEntities) 
      where T : class 
      where T1 : class 
     { 
      Set<T>().Attach(entity); 
      DeleteEntitiesAndSaveChanges(subEntities); 
     } 

public void DeleteEntitiesAndSaveChanges<T>(List<T> entities) where T : class 
     { 
      foreach (var entity in entities) 
      { 
       Set<T>().Attach(entity); 
       Set<T>().Remove(entity); 
      } 

      SaveChanges(); 
     } 

用途:

DbContext.DeleteEntityAndSaveChanges(request.ActivityType, request.ActivityType.ProductTypes); 

これは、生成されたSQLのthatsです:

exec sp_executesql N'delete [dbo].[ProductTypeActivityTypes] 
where (([ProductType_ProductTypeId] = @0) and ([ActivityType_EntityObjectId] = @1))',N'@0 bigint,@1 bigint',@0=1,@1=20 

これが送り出さたくない問題のSQLですが、されていますEFによって生成される:

EXEC sp_executesqlをN'delete [DBO]。[ProductTypes] ここで、(([ProductTypeId] = @ 0)および[タイムスタンプ]ヌルである)0 BIGINT @」、N ''、0 = 1

@どのように私はそれが関係を削除するだけで得ることができる任意のアイデア?

乾杯。

答えて

3

DbSetで[削除]を呼び出すと、これはSaveChangesが呼び出されたときにそのエンティティをデータベースから削除することを意味します。私が理解しているように、あなたが本当にやりたいことは、2つのエンティティ間の関連付けを削除することです。一般的には、他のエンティティのコレクションナビゲーションプロパティから1つのエンティティを削除します。例:

product.Activities.Remove(activity); 

ただし、ここにシワがあります。サンプルコードでは、Attachを呼び出して、両方のタイプのエンティティをコンテキストに添付します。 Attachを呼び出すと、エンティティ間の関係は設定も復元もされません。これは、多対多の関係の場合、エンティティが他のエンティティとどのように関係しているかに関する情報を提供するためのFKが存在しないためです。 FKは、EFの多対多マッピングでは公開されていない結合テーブルによって処理されます。

これに対処する方法はいくつかあります。まず、アーキテクチャに対して可能で賢明なものであれば、EFコンテキストではクエリーが行われてからSaveChangesを呼び出すまでエンティティを追跡できます。このようにして、EFはあなたの関係を追跡し、削除の追跡を含めます。

第2に、エンティティを新しいコンテキストにアタッチする必要がある場合は、リレーションシップを追跡して、それらも復元できるようにする必要があります。関係を復元するにはいくつかの方法があります。 1つの方法は、Attachを呼び出す前に関連するエンティティのグラフを作成することです。 EFは、Attachが呼び出されたときに、関係を含むグラフ全体をトラバースして添付します。たとえば:

// Restore the graph 
product.Activities.Add(activity1); 
product.Activities.Add(activity2); 
context.Products.Attach(product); 

// Delete the relationship 
product.Activities.Remove(activity1); 
context.SaveChanges(); 

(私はあなただけのコードが少し明確にする必要があり、一般的な方法を使用していないよそれはジェネリック医薬品と同じように動作するはずです。。)

関連する問題