禁用EF级联删除?

时间:2017-03-31 14:46:05

标签: entity-framework ef-fluent-api

我有两个按一对多关系链接的实体,如下所示(我先使用代码):

public class Computer
{
    [Key]
    public int ComputerId { get; set; }

    [Required]
    public int ComputerIdInventory { get; set; }

    [DataType(DataType.Date)]
    public DateTime? AcquisitionDate { get; set; }

    [DataType(DataType.Date)]
    public DateTime? LastUpdate { get; set; }

    public string Comment { get; set; }

    //Foreign keys
    public int? ComputerModelId { get; set; }

    public int? EmployeeId { get; set; }

    //Navigation properties
    public virtual ICollection<Screen> Screens { get; set; }
}

public class Screen
{
    [Key]
    public int ScreenId { get; set; }

    [Required]
    public int ScreenIdInventory { get; set; }

    public string Comment { get; set; }

    //Foreign keys
    public int? ComputerId { get; set; }

    //Navigation properties
    public virtual Computer Computer { get; set; }
}

当我删除链接到一个或多个屏幕的计算机时,出现以下错误:

  

[SqlException(0x80131904):DELETE语句与REFERENCE约束冲突&#34; FK_dbo.Screen_dbo.Computer_ComputerId&#34;。冲突发生在数据库&#34; CPInventory&#34;,table&#34; dbo.Screen&#34;,column&#39; ComputerId&#39;。

我读了很多帖子,我尝试了两件似乎对其他人有用的东西。我更改了&#34; OnModelCreating&#34;方法并补充说:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

我也尝试了这个:

modelBuilder.Entity<Computer>()
            .HasMany<Screen>(c => c.Screens)
            .WithOptional(s => s.Computer)
            .WillCascadeOnDelete(false);

但是没有一个解决方案有效......我做错了什么?我也更新了数据库但没有任何改变。我是否必须完全删除数据库并重新创建它才能将这些更改考虑在内?

非常感谢!

编辑: 这是删除代码

public ActionResult DeleteConfirmed(int id)
    {
        Computer computer = db.Computers.Find(id);
        db.Computers.Remove(computer);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

2 个答案:

答案 0 :(得分:0)

问题是数据库中有一个外键约束,如果数据库中有子行(屏幕),则表示无法删除父行(计算机)。

这就是您首先使用级联删除功能的原因,因此删除计算机也会删除屏幕。

您唯一的选择是在删除计算机之前删除所有具有相同ComputerID的屏幕。 (或者为什么不打开级联删除并让框架为您完成)

答案 1 :(得分:0)

您无法删除屏幕中ComputerId与计算机ComputerId匹配的计算机。

所以更新屏幕:

screen.ComputerId = null;

然后删除您的计算机

db.Set<Computer>().Remove(computer);

然后保存更改

db.SaveChanges();