【发布时间】:2019-07-12 02:47:05
【问题描述】:
我很难理解这种关系,以及如何为其设置级联删除设置。
- 有一个员工表,每个员工都有任意数量的句柄、附件和工作
- 有一个句柄表,其中每个句柄都属于一个员工,并且可以在一个工具中使用
- 有一个附件表,其中每个附件都属于一个员工,并且可以在一个工具中使用
- 有一个工具表,其中每个工具由一个附件和一个手柄组成,可用于任意数量的工作
- 有一个工作表,其中每个工作属于一个员工,并且可能有也可能没有使用的工具
注意:手柄和附件可能存在而不用于制作工具
简而言之:员工可以混合搭配手柄和附件来制作工具,然后在分配给他们的工作中使用工具。
此图显示了数据库是如何连接在一起的(欢迎提出更好的设计建议)
这就是模型的设置方式,作业模型具有对工具 FK (ToolId) 的可为空引用,因此作业可以在没有工具的情况下存在。
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public List<Handle> Handles { get; set; }
public List<Attachment> Attachments { get; set; }
public List<Job> Jobs { get; set; }
}
public class Handle
{
public int HandleId { get; set; }
public string Material { get; set; }
public double ExpectedLife { get; set; }
public double LifetimeMaintenance { get; set; }
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public List<Tool> Tools { get; set; }
}
public class Attachment
{
public int AttachmentId { get; set; }
public string Material { get; set; }
public string Type { get; set; }
public double ExpectedLife { get; set; }
public double LifetimeMaintenance { get; set; }
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public List<Tool> Tools { get; set; }
}
public class Tool
{
public int ToolId { get; set; }
public string OperationSpeed { get; set; }
public int HandleId { get; set; }
public Handle Handle { get; set; }
public int AttachmentId { get; set; }
public Attachment Attachment { get; set; }
public List<Job> Jobs { get; set; }
}
public class Job
{
public int JobId { get; set; }
public string Name { get; set; }
public double EffortRequired { get; set; }
public int EmployeeID { get; set; }
public Employee Employee { get; set; }
public int? ToolId { get; set; }
public Tool Tool { get; set; }
}
这就是创建数据库上下文的方式。有一个级联删除设置,用于在删除工具时将 Jobs (ToolId) 中的工具 FK 设置为 null(因此删除工具时不会删除作业)。
public class ToolsDbContext : DbContext
{
public ToolsDbContext(DbContextOptions<ToolsDbContext> options) : base(options)
{
}
public DbSet<Employee> employees { get; set; }
public DbSet<Handle> handles { get; set; }
public DbSet<Attachment> attachments { get; set; }
public DbSet<Tool> tools { get; set; }
public DbSet<Job> jobs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Tool>()
.HasMany(j => j.Jobs)
.WithOne(t => t.Tool)
.OnDelete(DeleteBehavior.SetNull);
}
}
创建迁移工作,但更新数据库失败并出现以下错误:
Introducing FOREIGN KEY constraint 'FK_tools_handles_HandleId' on table 'tools' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
我不太清楚如何理解这个错误。
深思熟虑:
- 如果一个句柄被删除,它将删除所有使用它的工具,这反过来又会将相关作业中的 ToolId 设置为 null
- 如果一个附件被删除,它会删除它所使用的所有工具,进而将相关作业中的 ToolId 设置为 null
- 如果一个工具被删除,它会将相关作业中的 ToolId 设置为 null
- 如果作业被删除,将不会产生级联效应
因此,我认为问题一定出在删除员工上,但我不明白为什么(还没有?)...
- 如果删除了员工,则应删除所有内容;它应该删除所有相关的作业、句柄和附件。然后那些被删除的句柄或附件应该反过来删除与它们相关的工具(不管什么先出现)。
所以有删除员工的级联路径,但我希望这一切都可以根据模型设置按原样工作......所以我需要在 dbcontext 中配置更多级联删除要求吗?如果是这样,我不确定它应该如何配置......
注意:如果没有数据库中的雇员模型,一切似乎都正常
【问题讨论】:
标签: c# asp.net-core .net-core orm entity-framework-core