简体   繁体   中英

Entity Framework cascade delete - cycles or multiple cascade paths

I have 4 classes

  • Component - contains info about classes and interfaces
  • Class , Interface - both contain list of methods
  • Method

Each component contains more classes and interfaces , each class and interface has more methods .

If I remove component I need to remove also classes , interfaces and their methods . Can you give me a hint how to configure OnModelCreating in order to solve that? It seems problematic having method for both class and interface .

I'm getting this error:

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

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {


         modelBuilder.Entity<Component>().
           HasMany(t => t.Classes).
           WithOptional().
           WillCascadeOnDelete();

        modelBuilder.Entity<Component>().
           HasMany(t => t.Interfaces).
           WithOptional().
           WillCascadeOnDelete();


        modelBuilder.Entity<Class>().
           HasMany(t => t.Methods).
           WithOptional().
           WillCascadeOnDelete();

       modelBuilder.Entity<Interface>().
          HasMany(t => t.Methods).
          WithOptional().
          WillCascadeOnDelete();


        modelBuilder.Conventions.Remove<ForeignKeyAssociationMultiplicityConvention>();

        base.OnModelCreating(modelBuilder);
    }

Component:

public class Component
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual List<Class> Classes { get; set; }
    public virtual List<Interface> Interfaces { get; set; }

    public Component()
    {
        Classes = new List<Class>();
        Interfaces = new List<Interface>();
    }
}

Class:

public class Class
{
    [Key]  
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<Method> Methods { get; set; }

    public Class()
    {
        Methods = new List<Method>();
    }
}

Interface:

public class Class
{
    [Key]  
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<Method> Methods { get; set; }

    public Class()
    {
        Methods = new List<Method>();
    }
}

Method:

public class Method
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
}

Since a method can be referenced by any number of classes and interfaces, I don't think you would want it to be deleted if one of those classes or interfaces was deleted. Instead, consider having a the Component own the methods and delete them.

I have not used EF code first so the syntax of this code may not be correct, but hopefully gets the point across:

modelBuilder.Entity<Component>().
    HasMany(t => t.Classes).
    WithOptional().
    WillCascadeOnDelete();

modelBuilder.Entity<Component>().
    HasMany(t => t.Interfaces).
    WithOptional().
    WillCascadeOnDelete();

modelBuilder.Entity<Component>().
    HasMany(t => t.Methods).
    WithOptional().
    WillCascadeOnDelete();

modelBuilder.Entity<Class>().
    HasMany(t => t.Methods).
    WithOptional();

modelBuilder.Entity<Interface>().
    HasMany(t => t.Methods).
    WithOptional();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM