更新迁移到数据库时出错:外键约束可能导致循环或多个级联路径

Posted

技术标签:

【中文标题】更新迁移到数据库时出错:外键约束可能导致循环或多个级联路径【英文标题】:Getting Error when updating Migration in to database : Foreign key constraint may cause cycles or multiple cascade paths 【发布时间】:2022-01-15 19:30:39 【问题描述】:

这个问题很容易复制,但我不知道解决它的正确方法。

类:

public class Employee : IEntity<Guid>

     public Guid Id  get; set; 
     public Guid ApplicationUserId  get; set; 
     public ApplicationUser ApplicationUser  get; set; 
     public Guid CompanyId  get; set; 
     public Company Company  get; set; 


public class Company : IEntity<Guid>

     public Guid Id  get; set; 
     public string Name  get; set; 
     public IList<Employee> Employees  get; set; 

我正在为用户表使用内置标识 ApplicationUser 类。 生成迁移时我没有收到任何错误,但每当我尝试更新数据库时,我都会收到错误:

在表 'Employee' 上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

使用 Fluent API 解决此问题的适当方法是什么?

项目类型:ASP.NET Core MVC

【问题讨论】:

您显示的类没有多个或循环级联路径。必须涉及其他外键。无论如何,通常的解决方法是:将至少一个关系配置为非级联。请查看有关此错误的众多问题。 其实我还有一个依赖于 Company 类的实体类。 【参考方案1】:

第一个过程:-

首先将您的迁移文件(cascadeDelete: true) 转换为(cascadeDelete: false),如果仍然无法正常工作,请继续。

使您的外键属性可以为空,这应该可以工作。

更新您的代码如下:-

public class Employee : IEntity<Guid>

     public Guid Id  get; set; 

     [ForeignKey("ApplicationUserId")]
     public virtual  ApplicationUser ApplicationUser  get; set; 
     public Guid? ApplicationUserId  get; set; 
     
     [ForeignKey("CompanyId")]
     public virtual Company Company  get; set; 
     public Guid? CompanyId  get; set; 
     

如果不起作用,请尝试第二个过程:-

public class Employee : IEntity<Guid>

     public Guid Id  get; set; 
    
     public Guid ApplicationUserId  get; set; 
     public ApplicationUser ApplicationUser  get; set; 
     
     public Guid CompanyId  get; set; 
     public Company Company  get; set; 
     
     

将此添加到您的 DbContext 类中:-

 protected override void OnModelCreating(ModelBuilder modelbuilder) 

         

            base.OnModelCreating(modelbuilder);
            modelbuilder.Entity<Employee>() 

                .HasOne(b => b.ApplicationUser )       

                .WithMany(ba => ba.Employee)  

                .HasForeignKey(bi => bi.ApplicationUserId ); 
 //For Company

            modelbuilder.Entity<Employee>() 

               .HasOne(b => b.Company )        

               .WithMany(ba => ba.Employee)   

               .HasForeignKey(bi => bi.CompanyId);  
         

 

第三过程:-

另一种选择是通过添加此 (EF6) 来删除所有 CASCADE DELETES:-

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

希望它能解决您的问题。

【讨论】:

不,他们只有必须将一个 FK 配置为非级联,仅此而已。不应更改迁移文件,也不应通过使键为空来更改性质关系。 @gert-arnold 我试着听从你的建议。实际上它有效。 好的,那么我宁愿看到这个答案被修改。目前,它充满了坏主意。【参考方案2】:

这个问题的解决方法是:

只需将一个 FK 配置为非级联,仅此而已。移民 文件不应该被改变,性质关系不应该 通过使键可以为空来更改。 - @gert-arnold

【讨论】:

以上是关于更新迁移到数据库时出错:外键约束可能导致循环或多个级联路径的主要内容,如果未能解决你的问题,请参考以下文章

外键约束可能导致循环或多个级联路径[重复]

SQL Server 引入 FOREIGN KEY 约束可能导致循环或多个级联路径

:完整性约束违规:1452 无法添加或更新子行:laravel 迁移中的外键约束失败

Laravel 迁移 - 违反完整性约束:1452 无法添加或更新子行:外键约束失败

MSSQL约束可能导致循环或多个级联路径[重复]

引入 FOREIGN KEY 约束可能会导致循环或多个级联路径 - 为啥?