0

I have an entity that has child two collections that implement a many to many relationship.

Error: Introducing FOREIGN KEY constraint 'FK_dbo.ClassCClassBs_dbo.ClassBs_ClassB_Id' on table 'ClassCClassBs' 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. See previous errors.

Using EF 6

public class ClassA
{
    public int Id { get; set; }
    public virtual ICollection<ClassB> ClassBs { get; set; }
    public virtual ICollection<ClassC> ClassCs { get; set; }
}

public class ClassB
{
    public int Id { get; set; }
    public int ClassAId { get; set; }
    public virtual ClassA ClassA { get; set; }
    public virtual ICollection<ClassC> ClassCs { get; set; }
}

public class ClassC
{
    public int Id { get; set; }
    public int ClassAId { get; set; }
    public virtual ClassA ClassA { get; set; }
    public virtual ICollection<ClassB> ClassBs { get; set; }
}

Edit: I want to configure it in a way that when Entity A is deleted, Entity B and C are also deleted, including their associated many to many associations.

UPDATE:

I created another class representing the many to many association from Class B and C.

Idea taken from How to create a many-to-many mapping in Entity Framework?

public class ClassBClassC
{
    public int ClassBId { get; set; }
    public int ClassCId { get; set; }
    public virtual ClassB ClassB { get; set; }
    public virtual ClassC ClassC { get; set; }
}

Also I overrode the OnModelCreated to configure the new class and only set cascade delete to one of the associations.

 public class ClassContext : DbContext
{
    public ClassContext() : base("DefaultConnection")
    {
    }
    public DbSet<ClassA> ClassAs { get; set; }
    public DbSet<ClassB> ClassBs { get; set; }
    public DbSet<ClassC> ClassCs { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ClassBClassC>().HasKey(c => new { c.ClassBId, c.ClassCId });
        modelBuilder.Entity<ClassB>().HasMany(c => c.ClassBClassCs).WithRequired(c => c.ClassB).HasForeignKey(c => c.ClassBId).WillCascadeOnDelete(true);
        modelBuilder.Entity<ClassC>().HasMany(c => c.ClassBClassCs).WithRequired(c => c.ClassC).HasForeignKey(c => c.ClassCId).WillCascadeOnDelete(false);
    }
}

This modification will cascade delete Entity B and C when I delete Entity A. The only thing to keep in mind is that I would have to manually delete the many to many associations in Entity C when deleted.

Community
  • 1
  • 1
Andres Ramos
  • 608
  • 6
  • 8

1 Answers1

0

You need to override the OnModelCreating method and specify the relations between tables:

modelBuilder.Entity<ClassB>()
    .HasRequired(p => p.ClassA)
    .WithMany(p => p.ClassBs)
    .HasForeignKey(p => p.ClassAId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<ClassC>()
    .HasRequired(p => p.ClassA)
    .WithMany(p => p.ClassCs)
    .HasForeignKey(p => p.ClassAId)
    .WillCascadeOnDelete(false);
Cristian Szpisjak
  • 2,429
  • 2
  • 19
  • 32
  • Is there a way to delete Entity B and C to whenever I delete Entity A? – Andres Ramos Mar 28 '17 at 17:05
  • Set the value to `true` instead of `.WillCascadeOnDelete(false)` – Cristian Szpisjak Mar 28 '17 at 17:10
  • I believe that by convention cascade delete is set to true but let me try by explicitly configuring it to true and I'll update. – Andres Ramos Mar 28 '17 at 17:14
  • I added an update with a possible solution. Your answer would only work by setting cascade delete on only one of the collection associations in Entity A, but I would have to remember to manually remove the other association first before deleting the rest. – Andres Ramos Mar 28 '17 at 17:50