none
EF Core Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths RRS feed

  • Question

  • Hey guys,

    I'm trying to create my Code First EF Core model. I thought I understood the cascade mechanic but somehow the following fluent configuration throws the exception from the title. I was playing around but most of the problems are with the entity DEFECT. I just can't see where I'm wrong.

    fluent api:

     builder.Entity<ApplicationUser>().HasMany(u => u.Claims).WithOne().HasForeignKey(c => c.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
                builder.Entity<ApplicationUser>().HasMany(u => u.Roles).WithOne().HasForeignKey(r => r.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
                
                builder.Entity<ApplicationRole>().HasMany(r => r.Claims).WithOne().HasForeignKey(c => c.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);
                builder.Entity<ApplicationRole>().HasMany(r => r.Users).WithOne().HasForeignKey(r => r.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);
    
                builder.Entity<Customer>().HasIndex(c => c.Name);
                builder.Entity<Customer>().HasOne(a => a.ConnectedCustomer).WithOne().HasForeignKey<Customer>(fk => fk.ConnectedCustomerId);
    
                builder.Entity<Policy>().HasIndex(p => p.Number);
                builder.Entity<Policy>().HasOne(a => a.Customer).WithMany(b => b.Policies).HasForeignKey(fk => fk.CustomerId).OnDelete(DeleteBehavior.Cascade);
                builder.Entity<Policy>().HasOne(a => a.Category).WithMany(b => b.Policies).HasForeignKey(fk => fk.CategoryId).OnDelete(DeleteBehavior.SetNull);
                builder.Entity<Policy>().HasOne(a => a.ManagedBy).WithMany(b => b.ManagedPolicies).HasForeignKey(fk => fk.ManagedById).OnDelete(DeleteBehavior.SetNull);
                builder.Entity<Policy>().HasOne(a => a.PolicyBefore).WithOne().HasForeignKey<Policy>(f => f.PolicyBeforeId);
                builder.Entity<Policy>().HasOne(a => a.PolicyNext).WithOne().HasForeignKey<Policy>(f => f.PolicyNextId);
    
                builder.Entity<Defect>().HasIndex(d => d.Number);
                builder.Entity<Defect>().HasOne(a => a.Policy).WithMany(b => b.Defects).HasForeignKey(fk => fk.PolicyId).OnDelete(DeleteBehavior.Cascade);
                builder.Entity<Defect>().HasOne(a => a.ClosedByUser).WithMany(b => b.ClosedDefects).HasForeignKey(fk => fk.ClosedByUserId).OnDelete(DeleteBehavior.SetNull);
                builder.Entity<Defect>().HasOne(a => a.ResponsibleUser).WithMany(b => b.ResponsibleForDefects).HasForeignKey(fk => fk.ResponsibleUserId).OnDelete(DeleteBehavior.SetNull);
    
                builder.Entity<PolicyCategory>().Property(p => p.Name).IsRequired();
    
                builder.Entity<UserTask>().HasOne(a => a.Customer).WithMany(b => b.Tasks).HasForeignKey(fk => fk.CustomerId).OnDelete(DeleteBehavior.SetNull);
                builder.Entity<UserTask>().HasOne(a => a.Policy).WithMany(b => b.Tasks).HasForeignKey(fk => fk.PoliyId).OnDelete(DeleteBehavior.SetNull);
                builder.Entity<UserTask>().HasOne(a => a.Defect).WithMany(b => b.Tasks).HasForeignKey(fk => fk.DefectId).OnDelete(DeleteBehavior.SetNull);
                builder.Entity<UserTask>().HasOne(a => a.User).WithMany(b => b.Tasks).HasForeignKey(fk => fk.UserId).OnDelete(DeleteBehavior.SetNull);
    
                builder.Entity<ApplicationFile>().HasOne(o => o.Customer).WithMany(f => f.Files).OnDelete(DeleteBehavior.Cascade);
                builder.Entity<ApplicationFile>().HasOne(o => o.Defect).WithMany(f => f.Files).OnDelete(DeleteBehavior.Cascade);
                builder.Entity<ApplicationFile>().HasOne(o => o.Policy).WithMany(f => f.Files).OnDelete(DeleteBehavior.Cascade);
                builder.Entity<ApplicationFile>().HasOne(o => o.Task).WithMany(f => f.Files).OnDelete(DeleteBehavior.Cascade);
                builder.Entity<ApplicationFile>().HasOne(o => o.Categories).WithMany(f => f.Files).OnDelete(DeleteBehavior.Cascade);
            }


    All the entities have the same structure, so a virtual collection property on one end and a navigation property on the other:

    Defect:

    public int Id { get; set; }
            public string Number { get; set; }
            public string Name { get; set; }
            public string Info { get; set; }
            public DateTime DefectDate { get; set; }
            public DateTime ReportDate { get; set; }
            public DateTime? ClosingDate { get; set; }
    
            public virtual ApplicationUser ResponsibleUser { get; set; }
            public string ResponsibleUserId { get; set; }
    
            public virtual ApplicationUser ClosedByUser { get; set; }
            public string ClosedByUserId { get; set; }
            
            public virtual Policy Policy { get; set; }
            public int PolicyId { get; set; }
    
            public virtual ICollection<ApplicationFile> Files { get; set; }
            public virtual ICollection<UserTask> Tasks { get; set; }


    Application User:

     public virtual ICollection<Defect> ResponsibleForDefects { get; set; }
            public virtual ICollection<Defect> ClosedDefects { get; set; }

    And the error: 

    Introducing FOREIGN KEY constraint 'FK_Defects_AspNetUsers_ResponsibleUserId' on table 'Defects' 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.

    Any idea where I'm wrong?

    Thanks!

    Wednesday, February 14, 2018 12:44 AM

Answers

All replies