Home > Net >  Update-Database throwing FK cascade error (EF Core / C# / ASP.NET Core)
Update-Database throwing FK cascade error (EF Core / C# / ASP.NET Core)

Time:06-06

I am having a problem where I am trying to set up a code-first database through EF Core, and running into a problem when attempting to replicate the relationship between an employee and a manager (also and employee). When trying to run Update-Database in the Package manager I get this error:

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

Failed executing DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [ManagerRelations] (
[EmployeeID] int NOT NULL,
[ManagerID] int NOT NULL,
CONSTRAINT [PK_ManagerRelations] PRIMARY KEY ([ManagerID], [EmployeeID]),
CONSTRAINT [FK_ManagerRelations_Employees_EmployeeID] FOREIGN KEY ([EmployeeID]) REFERENCES [Employees] ([EmployeeID]) ON DELETE CASCADE,
CONSTRAINT [FK_ManagerRelations_Employees_ManagerID] FOREIGN KEY ([ManagerID]) REFERENCES [Employees] ([EmployeeID]) ON DELETE CASCADE );

Here are the relevant models and the DbContext:

ManagerEmployeeRelation:

public class ManagerEmployeeRelation
{
    [Key, Column(Order = 1)]
    public int EmployeeID { get; set; }
    [Key, Column(Order = 2)]
    public int ManagerID { get; set; }
    public Employee? Manager { get; set; }
    public Employee? Employee { get; set; }
}

For the '?'s I found THIS question which has been asked previously, and tried '?'s on both ID fields, and Employee Objects as shown above.

Employee:

public class Employee
{
    [HiddenInput]
    [Key]
    public int EmployeeID { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [HiddenInput]
    public string EmployeeName { get; set; }

    [Required]
    public string FName { get; set; }

    [Required]
    public string LName { get; set; }

    [HiddenInput]
    [DataType(DataType.EmailAddress)]
    public string EMail { get; set; }
    
    [HiddenInput]
    [DataType(DataType.EmailAddress)]
    public string NormalizedEmail { get; set; }

    [Required]
    public string JobTitle { get; set; }

    [DataType(DataType.Currency)]
    public int Salary { get; set; }
     
    [DataType(DataType.Date)]
    public DateTime OnboardingDate { get; set; }

    public Department EmployeeDepartment { get; set; }

    public bool IsActive { get; set; }
    public bool IsManager { get; set; }

    public DateTime LastLogin { get; set; }
}

CompanyContext (DbContext):

public class CompanyContext : DbContext
{
    public CompanyContext(DbContextOptions<CompanyContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ManagerEmployeeRelation>().HasKey(M => new { M.ManagerID, M.EmployeeID});
    }

    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
    public DbSet<UserGroup> UserGroups { get; set; }
    public DbSet<AccessLevel> AccessLevels { get; set; }
    public DbSet<Application> Applications { get; set;}
    public DbSet<ManagerEmployeeRelation> ManagerRelations { get; set; }
}

Here I believe I manually set the primary key correctly according to THIS question's answer.

I guess I am stuck because I see questions about this being asked, but it does not seem like the solutions are working for me, OR I am not implementing the solutions correctly (Which is highly likely). Can someone please advise on what else I can try? Or if I even implemented the solution from the first question correctly?

CodePudding user response:

As shown in this answer to related question: EF Core - may cause cycles or multiple cascade paths

you have to configure OnDelete() for each foreign key.

  • Related