2017-07-13 41 views
0

假設我有一個帶有表A和表B的數據庫.B對於表A有一個外鍵,它不允許有空值。當我嘗試刪除A的實體時,我希望刪除表B中的所有引用。我嘗試用下面的代碼來做到這一點:DELETE語句在Database First中發生衝突

using (var ctx = new MyDatabaseContext(ConnectionString)) 
{ 
    var a= new A() { IdA= idA}; 
    ctx.A.Attach(a); 
    ctx.A.Remove(a); 
    ctx.SaveChanges(); 
} 

這將導致以下錯誤消息:

附加信息:DELETE語句衝突與基準約束「FK_B_A」。數據庫「MyDatabase」中出現衝突,表「dbo.B」,列'IdA'。

該聲明已終止。

我已經嘗試了很多,從使用數據庫中的觸發器來定義ON DELETE CASCADE,但實體框架確實失敗。我究竟做錯了什麼?

觸發:

ALTER TRIGGER [dbo].[trg_DelA] 
ON [dbo].[A] 
FOR DELETE AS 
    BEGIN 
    DELETE FROM B WHERE B.IdA = IdA; 
    END 

順便說一句:這僅僅是一個例子。實際的數據庫較大,並且還包含多對多關係的中間表。

BR 托馬斯

+0

你能提供可重現的例子嗎?表A上的級聯刪除和刪除觸發器都可以工作,這並不重要 - 刪除可以通過EF或手動調用。你在數據庫方面究竟做了什麼? –

+0

我將觸發器代碼添加到我的帖子 –

回答

2

AFTER(或FOR - 它們是同義詞)觸發的後解僱觸發SQL語句。在你的情況下,這太遲了,因爲刪除語句不能由於外鍵完成。

如果要使用觸發器處理級聯刪除 - 必須使用instead of觸發器,並且在此觸發器中首先從B表中刪除記錄,然後從A表中刪除記錄。

因此,這可能看起來像:

CREATE TRIGGER [dbo].[trg_DelA] 
ON [dbo].[A] 
INSTEAD OF DELETE AS 
BEGIN 
    DELETE FROM B WHERE B.IdA in (select IdA from deleted) 
    DELETE FROM A WHERE IdA in (select IdA from deleted) 
END 

參考見MSDN

+0

哦,我明白了。所以沒有BEFORE但只有INSTEAD觸發器?當我嘗試添加此觸發器時,我收到以下消息:無法在表'dbo.Harnesses'上更改INSTEAD DELETE或INSTEAD UPDATE TRIGGER'trg_DelHarness'。這是因爲表中有一個級聯DELETE或UPDATE的FOREIGN KEY –

+0

我將嘗試從外鍵刪除級聯 –

+0

現在我可以創建觸發器 –

相關問題