[英]How to configure cascade delete where there are cycles and multiple cascade paths
我很难理解这种关系,以及如何为它设置级联删除设置。
注意:句柄和附件可能存在而没有用于制作工具
简而言之:员工可以混合使用手柄和附件来制作工具,然后在分配给他们的工作中使用工具。
该图显示了数据库是如何连接在一起的(可以随时提出更好的设计建议 )
这就是模型的设置方式,“作业”模型对工具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; }
}
这就是创建数据库上下文的方式。 有一个级联删除设置,用于在删除工具时将“作业”中的工具FK(ToolId)设置为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.
我不太确定如何理解此错误。
通过以下方式进行思考:
因此,我认为问题一定出在删除雇员上,但是我不明白为什么(还?)...
因此,有一些级联路径删除了一个雇员,但是我希望这一切都将根据模型设置保持原样。 如果是这样,我不确定应该如何配置...
注意:如果数据库中没有员工模型,一切似乎都可以正常工作
SQL Server不允许在数据库中具有指向同一表的多个级联路径。 在您的情况下,其中有两个工具:
解决此问题的所有方法都包括为一个关系或另一个关系设置DeleteBehavior.Restrict,例如:
等等...
你说:
有一张员工表,其中每个员工都有任意数量的手柄,附件和作业
但是您的图在一个员工和一个手柄之间建立了直接链接,一个手柄有很多员工,而一个员工只有一个手柄
您的陈述与图表冲突
从数据库的角度来看,我认为这种建模是错误的。 我认为工作应该有雇员。 (如果一个工作有多个雇员,则需要另一个表雇员将一个工作ID映射到多个雇员。)一个工作有一个工具,一个工具有一个手柄和一个附件。 我看不到为什么删除雇员应该删除他们的工作(如果我解雇了某人,但他为我工作时盖的房子仍然存在),但是您可以在不使用级联约束的情况下进行清理
最终,您可以在图中看到已创建的循环。 如果删除1端的内容会删除*端的所有内容,则删除图表中的任何内容都会启动一条链,该链采用一条分离的路径,该路径会重新组合在一起。 删除员工实体确实可以解决这个问题
最终,员工不应直接拥有工作,把手或附件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.