2013-12-17 72 views
3

假設我有這樣的場景:EF刪除試圖更新外鍵

Table Bar 
Id int not null 
Name string not null 

Table Foo 
Id int not nul 
BarId int foreign key (Bar) references Id 

當我嘗試刪除具有Foo中,參考爲什麼EF試圖更新吧Foo將BarId設置爲NULL?

我有一個驗證我的財產,當有人試圖設置爲NULL條,並收到此錯誤時,EF試圖更新富。

如果我嘗試刪除執行類似的查詢「從富刪除其中id = 1」我得到:

The DELETE statement conflicted with the REFERENCE constraint "FooFK". 
The conflict occurred in database "teste", table "dbo.Bar", column 'BarId'. 

我想,當我使用EF得到這個錯誤。有沒有辦法做到這一點? 我使用EF 4.3。

這是我的地圖:

modelBuilder.Entity<Bar>().HasRequired(x => x.Foo).WithMany().Map(x => x.MapKey("FooId")).WillCascadeOnDelete(false); 
+0

它試圖BarId設置爲空由於該約束。您沒有級聯刪除,並且外鍵列需要值或null。你能發佈你的約束嗎? – scheien

+0

但我的列不接受NULL。 –

+0

約束: ALTER TABLE [dbo]。[Cargo] WITH CHECK ADD CONSTRAINT [CargoRaiz_Instituicao] FOREIGN KEY([Instituicao_Id]) REFERENCES [dbo]。[Instituicao]([Id]) –

回答

0

它不是通常是正確的,你可以用兩種方法「從數據庫中刪除項目」。確切地說,它是這樣的:

ObjectContext.DeleteObject(entity)在上下文中將實體標記爲Deleted。 (之後它的EntityState被刪除。)如果您之後調用SaveChanges,則EF將SQL DELETE語句發送到數據庫。如果數據庫中沒有引用約束被違犯,則實體將被刪除,否則引發異常。

EntityCollection.Remove(childEntity)將parent和childEntity之間的關係標記爲Deleted。如果從數據庫中刪除了childEntity本身,並且在調用SaveChanges時發生了什麼取決於兩者之間的關係類型:

如果關係是可選的,即從子項引用父項的外鍵數據庫允許NULL值,這個外部將被設置爲null,如果你調用SaveChanges,這個childEntity的NULL值將被寫入數據庫(即兩者之間的關係被刪除)。這發生在SQL UPDATE語句中。沒有DELETE語句發生。

如果需要關係(FK不允許NULL值)並且關係不能識別(這意味着外鍵不是孩子的(複合)主鍵的一部分),您必須添加孩子到另一個家長,或者你必須顯式刪除孩子(然後使用DeleteObject)。如果您沒有執行任何這些操作,則會違反引用約束,並且在您調用SaveChanges時EF會引發異常 - 臭名昭着的「由於一個或多個外鍵屬性是不可空的,因此無法更改關係」異常或類似的。

如果關係正在識別(它必然需要,那麼因爲主鍵的任何部分都不能爲空),EF會將childEntity標記爲已刪除。如果調用SaveChanges,則會將SQL DELETE語句發送到數據庫。如果數據庫中沒有其他引用約束被違犯,則實體將被刪除,否則引發異常。

我實際上對你關聯的MSDN頁面上的備註部分有點困惑,因爲它說:「如果關係有一個參照完整性約束,調用依賴對象的Remove方法標記關係和依賴關係刪除對象「。這對我來說似乎是不準確的,甚至是錯誤的,因爲上述三種情況都有「參照完整性約束」,但只有在最後一種情況下才會刪除孩子。 (除非他們的意思與「依賴對象」,在一個確定的關係這將是一個不尋常的術語雖然參與的對象。)

來源:http://bit.ly/1bNMyF5