【问题标题】:Asp net - Delete record from db using OnDelete()Asp net - 使用 OnDelete() 从数据库中删除记录
【发布时间】:2019-11-02 15:37:06
【问题描述】:

尝试使用 Asp Net Core 创建简单的 CRUD 应用程序。我有 2 个实体: 部门和员工(一对多)。我需要从部门表中删除记录。但是当我尝试使用OnDelete(DeleteBehavior.Restrict)OnDelete(DeleteBehavior.ClientSetNull) 删除记录时,我遇到了异常:

表“Departments”中的 UPDATE 或 DELETE 违反外键约束 “FK_Employees_Departments_DepartmentCode”表“员工”

我该如何解决这个问题? 实体员工:

public class Employee
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        [Required(ErrorMessage = "Input fullname of employee")]
        public string FullName { get; set; }
        [Required(ErrorMessage = "Input date of birth")]
        public DateTime DateOfBirth { get; set; }
        [Required(ErrorMessage = "Input code")]
        public string Code { get; set; }
        [Required(ErrorMessage = "Input fullname of employee")]
        public int Salary { get; set; }

        public string DepartmentCode { get; set; } 
        public Department Department { get; set; }
    }

实体部门:

public class Department
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        [Required(ErrorMessage = "Input name of department")]
        public string Name { get; set; }
        [Required(ErrorMessage = "Input code of department")]
        public string Code { get; set; }
        public ICollection<Employee> Employees { get; set; }
        public Department()
        {
            Employees = new List<Employee>();
        }
    }

上下文类设置:

protected override void OnModelCreating(ModelBuilder modelBuilder)

{
        modelBuilder.Entity<Department>()
            .HasMany<Employee>(d => d.Employees)
            .WithOne(e => e.Department)
            .HasForeignKey(e => e.DepartmentCode)
            .OnDelete(DeleteBehavior.Restrict);

        modelBuilder.Entity<Department>()
            .HasKey(d => d.Code);

        modelBuilder.Entity<Employee>()
            .HasKey(e => e.Code);

        modelBuilder.Entity<Department>()
            .HasIndex(d => d.Name).IsUnique();
    }

【问题讨论】:

  • 删除部门后是否要删除员工?我会在您的架构中引入一个新表。一个 EmployeeDepartment 表。这将是一个更好的设计 IMO。
  • 不,我想删除部门而不级联删除员工。

标签: postgresql asp.net-core entity-framework-core


【解决方案1】:

DeleteBehavior 枚举中的所有字段中,只有两个实际上将级联外键行为添加到数据库:CascadeSetNull。所有其他选项创建外键时不执行删除操作,但 EF 将对其跟踪的实体执行的操作有所不同。

在您的情况下,它可能应该是SetNull,因为我假设员工可以在没有部门的情况下存在。此设置将允许您删除 Department 对象而不加载其 Employees。数据库会将他们的DepartmentCode 设置为null

【讨论】:

    【解决方案2】:

    EF 中配置的删除行为只能应用于 EF 更改跟踪所跟踪的实体。因此,您需要加载属于该部门的所有员工才能按预期工作。

    但是,数据库外键定义还定义了 on delete 操作(级联、设置 null、什么都不做)因此,即使您在上下文中编写了 set null 策略,数据库仍然可能对 on delete 应用不同的策略。 EF核心默认级联删除。

    【讨论】:

    • 那么,如果我想删除部门表中的记录,我需要加载属于部门的所有员工并将部门值设置为空?像那样 ? foreach(repo.Employees.ToList() 中的变量 e) { if(e.DepartmentId == department.Id) { e.DepartmentId = null; } 继续; } repo.Departments.Remove(部门); repo.SaveChanges();
    • 否 - 您需要查看您的数据库架构以了解如何配置外键。也许你需要调整它,也许你不能,也许你不需要改变任何东西。然后你相​​应地设置 EF。也许数据库中的外键配置为不允许空值,那么您不能在 EF 中设置空值,否则保存时会出错。如果数据库中允许空值,您可以加载包括员工在内的部门,然后删除部门,EF 将自动执行正确的操作。如果您在数据库中的外键配置为设置空值,您可以删除部门
    • 如何删除取决于我们不知道的设置
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2011-07-12
    • 2016-12-10
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多