为什么我的 Linq to Entities 代码会重复行?
我正在使用 ADO.NET 实体框架来管理对象的层次结构。 每个人都有单亲和零个或多个孩子。
具有父级和子级的 ADO.NET 实体框架对象 http://img14.imageshack.us/ img14/7158/thingpi1.gif
我在 WPF 应用程序中使用 TreeView 控件呈现这些内容。 单击按钮即可将新事物作为子项添加到所选事物中...
Visual Basic...
Private Sub ButtonAddThing_Click(...) Handles ButtonAddThing.Click Dim NewThing As New Thing NewThing.Id = Guid.NewGuid() NewThing.Parent = DirectCast(TreeViewThings.SelectedItem, Thing) ... db.AddToThing(NewThing) db.SaveChanges() TreeViewThings.UpdateLayout() End Sub
但是,有一个问题。 它不是简单地将新事物添加到数据库中,而是首先添加父事物的副本,但奇怪的是 Id 的唯一标识符为空。
这会使数据库变得混乱,并在第二次单击 ButtonAddThing 按钮后引发以下异常。
异常:“违反主键 约束“PK_Thing”。 无法插入 对象“dbo.Thing”中存在重复键。 该声明已终止。”
这些是生成的 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', ...
新事物:
exec sp_executesql N'insert [dbo].[Thing]([Id], [ParentId], ...) values (@0, @1, ...) ',N'@0 uniqueidentifier,@1 uniqueidentifier,...', @0='88641EBB-B7D7-4203-8191-B27E1D1E1840', @1='391FF0D9-40ED-4349-BB91-0F2E440EF8C9', ...
为什么我的 Linq to Entities 代码复制这些父级行?如何正确处理这种父/子关系?
更新:这不仅仅是创建新事物时的问题。我在调试应用程序时也无法
Private Sub ButtonDeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) db.SaveChanges() End Sub
监视
Private Sub ButtonDeleteThing_Click(...) Dim Id As Guid = DirectCast(TreeViewThings.SelectedItem, Thing).Id Dim DoomedThing As Thing = (From t In db.Thing _ Where t.Id = Id _ Select t).First db.DeleteObject(DoomedThing) db.SaveChanges() End Sub
SQL Server Profiler 观察到的行为:
- 单击第一个按钮即可正常。
- 单击第二个按钮会插入重复的父项(空 GUID uniqueidentifier 主键),然后执行删除,
- 单击第三个按钮会失败(违反 PRIMARY KEY 约束),因为它无法插入具有空 GUID 主键的第二个事物。
I'm using the ADO.NET Entity Framework to manage a hierarchy of objects. Each has a single parent and zero or more children.
I present these in my WPF application with a TreeView control. New Things may be added as children to the selected Things with the click of a button...
Visual Basic...
Private Sub ButtonAddThing_Click(...) Handles ButtonAddThing.Click Dim NewThing As New Thing NewThing.Id = Guid.NewGuid() NewThing.Parent = DirectCast(TreeViewThings.SelectedItem, Thing) ... db.AddToThing(NewThing) db.SaveChanges() TreeViewThings.UpdateLayout() End Sub
But, there's a problem. Rather than simply adding a new Thing to the database, it's also first adding a duplicate of the parent, but oddly with an empty uniqueidentifier for an Id.
This clutters up the database and throws the following exception after the second click of button ButtonAddThing.
Exception: "Violation of PRIMARY KEY
constraint 'PK_Thing'. Cannot insert
duplicate key in object 'dbo.Thing'.
The statement has been terminated."
These are the T-SQL insert statements generated...
The parent duplication:
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', ...
The new thing:
exec sp_executesql N'insert [dbo].[Thing]([Id], [ParentId], ...) values (@0, @1, ...) ',N'@0 uniqueidentifier,@1 uniqueidentifier,...', @0='88641EBB-B7D7-4203-8191-B27E1D1E1840', @1='391FF0D9-40ED-4349-BB91-0F2E440EF8C9', ...
Why is my Linq to Entities code duplicating these parent rows? How can I properly handle this parent/child relationship?
Update: It's not just a problem when creating new Things. My "delete" button isn't working properly either.
Private Sub ButtonDeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) db.SaveChanges() End Sub
nor
Private Sub ButtonDeleteThing_Click(...) Dim Id As Guid = DirectCast(TreeViewThings.SelectedItem, Thing).Id Dim DoomedThing As Thing = (From t In db.Thing _ Where t.Id = Id _ Select t).First db.DeleteObject(DoomedThing) db.SaveChanges() End Sub
I'm monitoring the SQL Server Profiler while I debug my application. Observed behavior:
- The first button click deletes just fine.
- The second button click inserts a duplicate-ish parent (empty GUID uniqueidentifier primary key) and then performs the delete.
- The third button click fails (Violation of PRIMARY KEY constraint) because it cannot insert a second Thing with an empty GUID primary key.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该能够执行以下操作:
这将构建您想要的分层模型。
You should be able to do something like this:
That will build the hierarchical model you are going for.