Я использую ADO.NET Entity Framework для управления иерархией объектов. У каждого есть один родитель и ноль или более детей.
Объект ADO.NET Entity Framework с родителями и дочерними элементами 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
Но есть проблема. Вместо простого добавления нового Thing в базу данных, он также сначала добавляет дубликат родителя, но странно с пустым уникальным идентификатором для идентификатора.
Это загромождает базу данных и выдает следующее исключение после второго нажатия кнопки 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 во время отладки приложения. Наблюдаемое поведение:
- Первое нажатие кнопки удаляет просто отлично.
- Вторым нажатием кнопки вставляется родительский элемент с дубликатом (пустой первичный ключ уникального идентификатора GUID), а затем выполняется удаление.
- Сбой третьего нажатия кнопки (нарушение ограничения PRIMARY KEY), поскольку он не может вставить вторую вещь с пустым первичным ключом GUID.