オブジェクトの階層を管理するためにADO.NETEntityFrameworkを使用しています。それぞれに単一の親と0個以上の子があります。
親と子を持つADO.NETEntityFrameworkオブジェクトhttp://img14.imageshack.us/img14/7158/thingpi1.gif
これらは、TreeViewコントロールを使用してWPFアプリケーションに表示します。ボタンをクリックするだけで、選択したものに子として新しいものを追加できます...
Visual Basic .. ..
Private Sub ButtonAddThing_Click(...)はButtonAddThing.Clickを処理します 新しいものとして薄暗いNewThing NewThing.Id = Guid.NewGuid() NewThing.Parent = DirectCast(TreeViewThings.SelectedItem、Thing) ..。 db.AddToThing(NewThing) db.SaveChanges() TreeViewThings.UpdateLayout() サブ終了
しかし、問題があります。単に新しいThingをデータベースに追加するのではなく、最初に親の複製を追加しますが、奇妙なことに、IDのuniqueidentifierは空です。
これによりデータベースが乱雑になり、ButtonAddThingボタンを2回クリックした後、次の例外がスローされます。
例外:「PRIMARYKEY制約'PK_Thing'の違反。オブジェクト'dbo.Thing'に重複するキーを挿入できません。ステートメントは終了しました。」
これらは、生成されたT-SQL挿入ステートメントです...
親の複製:
exec sp_executesql N'insert [dbo]。[Thing]([Id]、[ParentId]、...) 値(@ 0、@ 1、...)'、N' @ 0 uniqueidentifier、@ 1 uniqueidentifier、...'、 @ 0 = '00000000-0000-0000-0000-000000000000'、 @ 1 = '389D987D-79B1-4A9D-970F-CE15F5E3E18A'、 ..。
新しいこと:
exec sp_executesql N'insert [dbo]。[Thing]([Id]、[ParentId]、...) 値(@ 0、@ 1、...)'、N' @ 0 uniqueidentifier、@ 1 uniqueidentifier、...'、 @ 0 = '88641EBB-B7D7-4203-8191-B27E1D1E1840'、 @ 1 = '391FF0D9-40ED-4349-BB91-0F2E440EF8C9'、 ..。
Linq to Entitiesコードがこれらの親行を複製するのはなぜですか?この親子関係を適切に処理するにはどうすればよいですか?
更新:新しいものを作成するときの問題だけではありません。「削除」ボタンも正しく機能していません。
プライベートサブButtonDeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem、Thing)) db.SaveChanges() サブ終了
または
プライベートサブButtonDeleteThing_Click(...) Dim Id As Guid = DirectCast(TreeViewThings.SelectedItem、Thing).Id Dim DoomedThing As Thing =(From t In db.Thing _ ここで、t.Id = Id _ t)を選択します。最初に db.DeleteObject(DoomedThing) db.SaveChanges() サブ終了
アプリケーションのデバッグ中にSQLServerプロファイラーを監視しています。観察された行動:
- 最初のボタンクリックで問題なく削除されます。
- 2番目のボタンをクリックすると、重複した親(空のGUIDの一意の識別子の主キー)が挿入され、削除が実行されます。
- 3番目のボタンクリックは失敗します(PRIMARY KEY制約の違反)。これは、空のGUIDプライマリキーを持つ2番目のThingを挿入できないためです。