Как создать отношения с 3 способами в EF core 5

#c# #.net-core #entity-framework-core #entity-framework-core-5.0

Вопрос:

Я использую EntityFramework 5, и у меня есть модель, в которой у меня есть отношения «многие-ко-многим-ко-многим». Вот моя модель :

 public class User
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Email { get; set; }
    public UserStatus Status { get; set; } // Manager or user
    
    public ICollection<Contract> Contracts { get; set; }
}


public class Enterprise
{
    public int EnterpriseId{ get; set; }
    public string SIRET { get; set; }
    public string AdministrativeName { get; set; }
    public string PublicName { get; set; }
    public string Adress { get; set; }
    public string ZipCode { get; set; }
    public string City { get; set; }
    public string ContactEmail { set; get; }
    public string ContactName { get; set; }
    public string ContactPhoneNumber { get; set; }

    public ICollection<Contract> Contracts { get; set; }
}


public class Contract
{
    public int ContractId { get; set; }
    public int ConsultantId { get; set; }
    public User Consultant { get; set; }
    public int ManagerId { get; set; }
    public User Manager { get; set; }
    public int CustomerId { get; set; }
    public Enterprise Customer { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

protected override void OnModelCreating( ModelBuilder modelBuilder )
{
       modelBuilder.Entity<Contract>()
           .HasOne( c => c.Consultant )
           .WithMany( u => u.Contracts );

       /*modelBuilder.Entity<Contract>()
            .HasOne( c => c.Manager )
            .WithMany( m => m.Contracts );*/

       modelBuilder.Entity<Contract>()
            .HasOne( c => c.Customer )
            .WithMany( e => e.Contracts );

}
 

У меня есть сотрудник, который подписывает контракт с заказчиком. Каждый контракт контролируется менеджером.
Поскольку Пользователь может быть либо менеджером, либо сотрудником, у нас есть 2 ссылки на таблицу пользователей, но одна-на сотрудника, другая-на менеджера.

Пока что это не кажется слишком сложным, и скрипт «Добавить миграцию» работает хорошо. Но когда я пытаюсь запустить обновленную базу данных, я получаю следующий вывод :

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

Я попытался исправить это с помощью подсказки об ошибке, но это не возымело никакого эффекта.
Есть ли способ связать 3 сущности в EF Core, или мне нужно использовать другую модель ?

Спасибо

[Править] Я обновил код, который опубликовал

Комментарии:

1. Можете ли вы опубликовать, как вы создаете свой реферат в EF?

2. Нам нужен более актуальный код, чтобы помочь вам

3. Я обновил сообщение

Ответ №1:

Предполагая, что в каждом контракте есть менеджер и консультант, добавьте свойства навигации для пользователя

 public class User
{
    public int UserId { get; set; }
    .......

    public UserStatus Status { get; set; } // Manager or user

    public ICollection<Contract> UserContracts { get; set; }
    public ICollection<Contract> ManagerContracts { get; set; }
}
 

если в контракте может быть 1 менеджер, но несколько консультантов или также несколько менеджеров, вам понадобится еще один контракт за столом. В этом случае ваш пользователь будет выглядеть так

 public class User
{
    public int UserId { get; set; }
    .......

    public UserStatus Status { get; set; } // Manager or user

    public ICollection<ConsultanContract> UserContracts { get; set; }
    public ICollection<Contract> ManagerContracts { get; set; }
}
 

и вам придется отказаться от контракта

  public int ConsultantId { get; set; }
    public User Consultant { get; set; }
 

Ответ №2:

Это работает, но мне пришлось добавить некоторую конфигурацию в OnModelCreating

 protected override void OnModelCreating( ModelBuilder modelBuilder )
{
    modelBuilder.Entity<Contract>()
        .HasOne( c => c.Consultant )
        .WithMany( u => u.DevelopperContracts )
        .OnDelete(DeleteBehavior.NoAction);

    modelBuilder.Entity<Contract>()
        .HasOne( c => c.Manager )
        .WithMany( m => m.ManagerContracts )
        .OnDelete( DeleteBehavior.NoAction );

    modelBuilder.Entity<Contract>()
        .HasOne( c => c.Customer )
        .WithMany( e => e.Contracts )
        .OnDelete( DeleteBehavior.NoAction );
}