2016-05-26 4 views
0

私のSchool EF Modelには、KidsTutorialsが多対多の関係にあります。 キッズとチュートリアルの両方に既存のアイテムがあると仮定しましょう。既存の関係を変更するだけです。つまり、子供からいくつかのチュートリアルを追加/削除することです。エンティティフレームワーク多対多リレーションシップを正しく更新する

"Cannot insert duplicate key in object 'dbo.Tutorials'. The duplicate key value is (10)."

私はEFの新しいチュートリアルアイテムを作成しようとしている代わりに、私のための既存の関係を更新して見ることができます:私はこれを行うと

var kid; //the request target to modify relationships 
//kid.Tutorials has the old existing relationships to be modified by add/del 
var tutorialsToAdd; //the request to add relationships 
var tutorialsToDel; //the request to del relationships 
using (var conn = new SchoolEFModels(efConnectionStr)) { 
    conn.Kids.Attach(kid); 
    kid.Tutorials.ForEach(t => conn.Tutorials.Attach(t)); 
    kid.Tutorials.AddRange(tutorialsToAdd); //simple add extension in batch 
    kid.Tutorials.RemoveRange(tutorialsToDel); //simple del extension in batch 
    conn.SaveChanges(); 
} 

は、私が言って例外が発生しました。それは私が望まないものです。あなたは私をEFと誤解しました!

私のコードで何が問題になっていますか?多対多の関係を更新するにはどうすればよいですか?

+0

https://msdn.microsoft.com/en-us/magazine/dn166926.aspx –

+0

@GertArnold、それは私にMVC足場を販売しています。特に多対多の更新処理については言及していませんでした。私のアプリはそれとは異なる構造をしています。だから私はまだ失われている:( – Tom

答えて

0

私はそれを理解しました。

これを追加/削除すると、EntityStateが追加/削除されます。したがって、記事に記載されているように既存のIDを再挿入させるために、リンク先のGertに感謝します。あなたはEntityState.Modifiedconn.entry(kid/tutorials).Stateのそれぞれを変更してから、その後conn.SaveChanges();conn.ChangeTracker.DetectChanges();を呼び出す場合、予想通り

だから、それは唯一の多対多のテーブルを更新します。

更新日:

注意する必要があることは1つあります。キッズとチュートリアルのインメモリオブジェクトリストが互いにリンクされている場合。例えばKids[0].Tutorials[0] == Tutorials[0] && Tutorial[0].Kids[0] == Kids[0] EFはこのデッドループを処理できません。この円形リンクを最初に解除する必要があります。 私のアプローチは、Connectionを開いてKid Out Includes(チュートリアル)を読み込んでから、結果を使用して多対多の関係を更新しますが、メモリ内オブジェクトは使用しません。

関連する問題