我需要一些幫助來理解ADO.NET實體框架。ADO.NET實體框架生成意外的問題INSERT
我試圖用ADO.NET實體框架來表示和操縱WPF TreeView控件中的分層數據。
這些東西每個人都有一個單親家庭和零個或更多的孩子。
我的 「刪除」 按鈕...
Private Sub ButtonDeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) db.SaveChanges() End Sub
我監視SQL Server事件探查,同時調試我的應用程序:
- 的第一個按鈕點擊刪除就好了。
- 第二個按鈕單擊插入一個重複的父(但具有空的GUID uniqueidentifier主鍵),然後執行刪除。
- 第三個按鈕單擊失敗(違反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" ... />
的Visual Basic ...
Partial Public Class Window1 Dim db As New ThingProjectEntities Private Sub Window1_Loaded(...) Handles MyBase.Loaded TreeViewThings.ItemsSource = _ From t In db.Thing.Include("Children") _ Where (t.Parent Is Nothing) _ Select t End Sub Private Sub TreeViewThings_Expanded(...) Dim ExpandedTreeViewItem As TreeViewItem = _ DirectCast(e.OriginalSource, TreeViewItem) LoadTreeViewChildren(ExpandedTreeViewItem) End Sub Sub LoadTreeViewChildren(ByRef Parent As TreeViewItem) Dim ParentId As Guid = DirectCast(Parent.DataContext, Thing).Id Dim ChildThings As System.Linq.IQueryable(Of Thing) ChildThings = From t In db.Thing.Include("Children") _ Where t.Parent.Id = ParentId _ Select t Parent.ItemsSource = ChildThings End Sub Private Sub ButtonAddThing_Click(...) Dim NewThing As New Thing NewThing.Id = Guid.NewGuid() Dim ParentId As Guid = _ DirectCast(TreeViewThings.SelectedItem, Thing).Id NewThing.Parent = (From t In db.Thing _ Where t.Id = ParentId _ Select t).First ... db.AddToThing(NewThing) db.SaveChanges() TreeViewThings.UpdateLayout() End Sub Private Sub ButtonDeleteThing_Click(...) db.DeleteObject(DirectCast(TreeViewThings.SelectedItem, Thing)) db.SaveChanges() End Sub ... End Class
我在做什麼錯?爲什麼它會產生這些奇怪的插入物?
更新:
我已經取得了突破性進展。但是,我仍然無法解釋它。
當我爲這個問題簡化我的代碼時,我擺脫了原因。
而不是使用LINQ如:
From t In db.Thing.Include("Children") Where ...
我一直在使用LINQ如:
From t In db.Thing.Include("Children").Include("Brand") Where ...
你看,我的事實體是另一品牌的實體。
我認爲這是無關緊要的,所以我沒有在這個問題包括它上面。
顯然這是我的意外,問題插入我的事情表中的原因。
但是,爲什麼?任何人都可以解釋爲什麼會發生?我想更好地理解它。
我一次只刪除一件事。 – 2009-02-20 13:34:03
這就是「讓EF弄清楚做什麼」的一部分,這給我帶來麻煩。 – 2009-02-20 13:34:35
要刪除一個子對象,從對象圖中刪除它就足夠了。同樣,要添加一個新對象,請將其添加到對象圖中。 EF正在跟蹤圖表,以便在調用SaveChanges時知道該怎麼做。也許可以嘗試在你的用戶界面之外編寫一個單元測試,以瞭解它是如何工作的。 – 2009-02-20 17:30:56