为什么我的 Linq to Entities 代码会重复行?

发布于 2024-07-13 11:02:26 字数 2209 浏览 10 评论 0原文

我正在使用 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 观察到的行为:

  1. 单击第一个按钮即可正常。
  2. 单击第二个按钮会插入重复的父项(空 GUID uniqueidentifier 主键),然后执行删除,
  3. 单击第三个按钮会失败(违反 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.

ADO.NET Entity Framework Object with parent and children http://img14.imageshack.us/img14/7158/thingpi1.gif

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:

  1. The first button click deletes just fine.
  2. The second button click inserts a duplicate-ish parent (empty GUID uniqueidentifier primary key) and then performs the delete.
  3. The third button click fails (Violation of PRIMARY KEY constraint) because it cannot insert a second Thing with an empty GUID primary key.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情深已缘浅 2024-07-20 11:02:26

您应该能够执行以下操作:

Dim ParentId As Guid = DirectCast(TreeViewThings.SelectedItem, Thing).Id
NewThing.Parent = (From t In db.Thing _
                  Where t.Id = ParentId _
                  Select t).First

这将构建您想要的分层模型。

You should be able to do something like this:

Dim ParentId As Guid = DirectCast(TreeViewThings.SelectedItem, Thing).Id
NewThing.Parent = (From t In db.Thing _
                  Where t.Id = ParentId _
                  Select t).First

That will build the hierarchical model you are going for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文