ADO.NET Entity Framework を理解するための助けが必要です。
ADO.NET Entity Framework を使用して、WPF TreeView コントロールで階層データを表現および操作しようとしています。
親と子を持つ ADO.NET Entity Framework オブジェクト http://img14.imageshack.us/img14/7158/thingpi1.gif
これらの各 Thing には、1 つの親と 0 個以上の子があります。
私の「削除」ボタン...
Private Sub ButtonDeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) デシベル.SaveChanges() サブ終了
アプリケーションのデバッグ中に SQL Server プロファイラーを監視しています。
- 最初のボタンをクリックすると、問題なく削除されます。
- 2 回目のボタン クリックは、重複する親を挿入し (ただし、GUID の uniqueidentifier プライマリ キーは空)、削除を実行します。
- 空の GUID 主キーを持つ別の行を挿入できないため、3 回目のボタン クリックは失敗します (PRIMARY KEY 制約の違反)。
予期しない、生成された T-SQL の重複...
exec sp_executesql N'insert [dbo].[Thing]([Id], [ParentId], ...) 値 (@0, @1, ...) ',N'@0 一意識別子,@1 一意識別子,...', @0='00000000-0000-0000-0000-000000000000', @1='389D987D-79B1-4A9D-970F-CE15F5E3E18A', ...
しかし、ただの削除ではありません。私の「追加」ボタンは、予期しない挿入で同様の動作をします。それは同じパターンに従います。
これにより、これらのエンティティ クラスを WPF TreeView にバインドする方法やデータ モデル自体に、より根本的な問題があると思われます。
関連するコードは次のとおりです...
XAML...
<TreeView Name="TreeViewThings"
ItemsSource="{Binding}"
TreeViewItem.Expanded="TreeViewThings_Expanded"
TreeViewItem.Selected="TreeViewThings_Selected"
... >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Thing}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Path=Title}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
<Button Name="ButtonAddThing" Content="Add Thing" ... />
<Button Name="ButtonDeleteThing" Content="Delete Thing" ... />
ビジュアルベーシック...
部分公開クラス Window1 Dim db As New ThingProjectEntities Private Sub Window1_Loaded(...) ハンドル MyBase.Loaded TreeViewThings.ItemsSource = _ t から db.Thing.Include("Children") _ Where (t.Parent Is Nothing) _ を選択 サブ終了 プライベート サブ TreeViewThings_Expanded(...) 薄暗い ExpandedTreeViewItem を TreeViewItem として = _ DirectCast(e.OriginalSource, TreeViewItem) LoadTreeViewChildren(ExpandedTreeViewItem) サブ終了 Sub LoadTreeViewChildren(ByRef Parent As TreeViewItem) Guid = DirectCast(Parent.DataContext, Thing).Id として Dim ParentId System.Linq.IQueryable(Of Thing) としての薄暗い ChildThings ChildThings = From t In db.Thing.Include("Children") _ どこで t.Parent.Id = ParentId _ を選択 Parent.ItemsSource = ChildThings サブ終了 Private Sub ButtonAddThing_Click(...) NewThing を新しいものとして薄暗くする NewThing.Id = Guid.NewGuid() 親 ID を Guid として暗くする = _ DirectCast(TreeViewThings.SelectedItem, Thing).Id NewThing.Parent = (db.Thing の t から _ どこで t.Id = ParentId _ t).First を選択します。 ... デシベル。AddToThing(NewThing) デシベル.SaveChanges() TreeViewThings.UpdateLayout() サブ終了 Private Sub ButtonDeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) デシベル.SaveChanges() サブ終了 ... クラス終了
私は何を間違っていますか?なぜこれらの奇妙な挿入が生成されるのですか?
アップデート:
私は突破口を開きました。でも、いまだに説明できません。
この質問のコードを単純化したときに、原因を取り除きました。
次のようなLinqを使用するのではなく:
From t In db.Thing.Include("Children") どこで...
私は次のようなLinqを使用しています:
From t In db.Thing.Include("Children").Include("Brand") どこで...
ご覧のとおり、My Thing エンティティは別の Brand エンティティに関連付けられています。
関係ないと思ったので、上の質問には入れませんでした。
どうやらこれが、Thing テーブルへの予期しない問題の挿入の原因でした。
しかし、なぜ?なぜこれが起こったのか誰か説明できますか?私はそれをよりよく理解したいと思います。