2011-03-27 248 views
26

我在實體框架中刪除了一個問題。簡而言之,EF明確地試圖從數據庫中刪除一個實體,即使我已經明確地配置了EF來使用數據庫中的級聯刪除。使用實體框架級聯刪除 - 由EF刪除的相關實體

我的設計:

我有三個實體類型,MainEntityEntityTypeAEntityTypeB。在刪除EntityTypeAEntityTypeB時,EF已配置爲使用級聯刪除。換句話說,如果我刪除了一個MainEntity的實例,我希望所有相關的EntityTypeAEntityTypeB實例也被刪除。我從不刪除EntityTypeAEntityTypeB而不刪除其父母。

我的問題是,EF明確地發出DELETE聲明EntityTypeA,這導致我的應用程序崩潰。

這是我的模型是什麼樣子:

的關係具有以下非默認配置:

  • MainEntity -> EntityTypeA OnDelete: Cascade
  • MainEntity -> EntityTypeB OnDelete: Cascade

的關係EntityTypeA -> EntityTypeBOnDelete: None

數據庫內容

INSERT INTO MainEntities (Name) values ('Test') 
insert into EntityTypeA (MainEntityID) VALUES (1) 
insert into EntityTypeB (MainEntityID, EntityTypeAId) VALUES (1, 1) 
insert into EntityTypeB (MainEntityID, EntityTypeAId) VALUES (1, 1) 

我的代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var context = new Model1Container(); 
     var mainEntity = context.MainEntities.Include("EntityTypeA").SingleOrDefault(); 
     context.DeleteObject(mainEntity); 
     context.SaveChanges(); 
    } 
} 

當我打電話的SaveChanges,實體框架會發生什麼

在數據庫中執行以下操作:

exec sp_executesql N'delete [dbo].[EntityTypeA] 
where ([Id] = @0)',N'@0 int',@0=1 

這將導致外鍵衝突,因爲在EntityTypeB的表引用EntityTypeA實例項目。

問題

爲什麼實體框架的問題一個明確的刪除EntityTypeA的情況下,即使我已經配置實體框架使用級聯刪除?如果我刪除包含(「EntityTypeA」),它會再次開始工作。

+10

圖像(模型的)是不可用的 – flipchart 2014-02-25 06:27:08

回答

41

這正是級聯刪除在EF中的行爲方式。設置級聯關於EF設計器中的關係指示EF爲每個加載的相關實體執行DELETE語句。它沒有在數據庫中提到ON CASCADE DELETE

使用EF時設置級聯刪除需要兩個步驟:

  • 在EF設計關係設置級聯。這指示上下文必須在刪除父實體之前刪除所有加載的相關實體。如果沒有發生這種情況,EF會拋出異常,因爲內部狀態會檢測到已加載的孩子與任何現有的父實體無關,即使這種關係是必需的。我不確定在執行父實體的刪除語句之前或之後發生這種情況,但沒有區別。 EF在執行修改後不會重新加載相關實體,因此它不知道數據庫中觸發的級聯刪除。
  • 在數據庫中設置ON CASCADE DELETE關係。這將指示SQL在刪除父項時刪除未加載到上下文的所有相關記錄。

級聯刪除在EF中的實現很奇怪,效率很低,但這是它的行爲方式,如果你想使用它,你必須在這種情況下修改你的應用程序的行爲。

+2

感謝您的答覆! (當我生成我的數據庫模型sql腳本時,如果我在實體數據模型中啓用級聯,則EF在SQL語句中包含ON CASCADE DELETE,因此我擔心EF會依賴於此)。 – Nitramk 2011-03-27 11:45:57

5

除了在EF設計器上,還可以在數據庫中的FK Constraints上設置級聯刪除。

以下是Sql Server Management Studio(SSMS)關於如何設置級聯刪除的可視步驟。

注意完成後,在嘗試刪除之前,請不要忘記針對數據庫更新edmx

enter image description here

我更深入地在我的博客討論這個問題:Entity Framework Cascading Deletes; Set it from the database.