数据库优先发生冲突的DELETE语句

时间:2017-07-13 08:49:45

标签: sql sql-server database entity-framework-6

假设我有一个包含表A和表B的数据库.B有一个表A的外键,它不允许空值。当我尝试删除A的实体时,我希望删除表B中的所有引用。我尝试使用以下代码执行此操作:

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

这会导致以下错误消息:

  

附加信息:DELETE语句与REFERENCE约束“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

BTW:这只是一个例子。实际的数据库更大,并且还包含多对多关系的中间表。

BR 托马斯

2 个答案:

答案 0 :(得分:2)

AFTER(或FOR - 他们是同义词)触发器在触发SQL语句后触发。在你的情况下,这已经太晚了,因为由于外键而无法完成删除语句。

如果要使用触发器来处理级联删除 - 必须使用instead of触发器,并在此触发器中首先从B表中删除记录,然后从A表中删除记录。 / p>

所以这看起来像:

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以供参考。

答案 1 :(得分:1)