我需要一些帮助来理解 ADO.NET 实体框架。
我正在尝试使用 ADO.NET 实体框架表示和操作 WPF TreeView 控件中的分层数据。
ADO.NET 实体框架对象与父和子 http://img14.imageshack.us/img14/7158/thingpi1.gif
这些事物中的每一个都有一个单亲和零个或多个孩子。
我的“删除”按钮...
私有子按钮DeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) db.SaveChanges() 结束子
我在调试应用程序时正在监视 SQL Server Profiler:
- 第一个按钮单击删除就好了。
- 第二个按钮单击插入一个重复的父项(但具有空的 GUID 唯一标识符主键),然后执行删除。
- 第三个按钮单击失败(违反 PRIMARY KEY 约束),因为它无法插入具有空 GUID 主键的另一行。
意外生成的 T-SQL 重复...
exec sp_executesql N'insert [dbo].[Thing]([Id], [ParentId], ...) values (@0, @1, ...) ',N'@0 uniqueidentifier,@1 uniqueidentifier,...', @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" ... />
视觉基本...
部分公开课窗口1 Dim db 作为新事物ProjectEntities Private Sub Window1_Loaded(...) 处理 MyBase.Loaded TreeViewThings.ItemsSource = _ 从 t 在 db.Thing.Include("Children") _ 哪里(t.Parent 什么都不是)_ 选择 结束子 私有子 TreeViewThings_Expanded(...) 将 ExpandedTreeViewItem 调暗为 TreeViewItem = _ DirectCast(e.OriginalSource,TreeViewItem) LoadTreeViewChildren(ExpandedTreeViewItem) 结束子 Sub LoadTreeViewChildren(ByRef Parent As TreeViewItem) Dim ParentId As Guid = DirectCast(Parent.DataContext, Thing).Id 将 ChildThings 调暗为 System.Linq.IQueryable(Of Thing) ChildThings = From t In db.Thing.Include("Children") _ 其中 t.Parent.Id = ParentId _ 选择 Parent.ItemsSource = ChildThings 结束子 私有子按钮AddThing_Click(...) 将新事物视为新事物 NewThing.Id = Guid.NewGuid() 将 ParentId 调暗为 Guid = _ DirectCast(TreeViewThings.SelectedItem, Thing).Id NewThing.Parent =(从 t 在 db.Thing _ 其中 t.Id = ParentId _ 选择 t).First ... db.AddToThing(新事物) db.SaveChanges() TreeViewThings.UpdateLayout() 结束子 私有子按钮DeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) db.SaveChanges() 结束子 ... 结束类
我究竟做错了什么?为什么会产生这些奇怪的插入?
更新:
我取得了突破。但是,我还是无法解释。
当我为这个问题简化代码时,我已经摆脱了原因。
而不是使用 Linq,例如:
从 t 在 db.Thing.Include("Children") 哪里...
我一直在使用 Linq,例如:
From t In db.Thing.Include("Children").Include("Brand") where ...
您会看到,My Thing 实体与另一个 Brand 实体相关。
ADO.NET 实体框架对象与父子和相关对象 http://img25.imageshack.us/img25/3268/thingbrandct4.gif
我认为这无关紧要,所以我没有将其包含在上面的问题中。
显然,这是在我的 Thing 表中插入意外问题的原因。
但为什么?谁能解释为什么会这样?我想更好地理解它。