Net Core 3.1 EntityFramework - jak zaprojektować model bazy danych?

0

Witam. Posiadam 3 tabele:

        public DbSet<MachineReport> MachineReports { get; set; }
        public DbSet<MachineModel> Machines { get; set; }
        public DbSet<CustomerModel> Customers { get; set; }
        public DbSet<ApplicationUser> ApplicationUsers { get; set; }

Element z MachineReports jest przypisany do elementu z Machines
Element z Machines jest przypisany do elementu z Customers

i teraz pojawia się problem, bo ApplicationUsers to w zależności od ról "serwisanci", "klienci" lub "sprzedawcy".

  1. Do elementu Customers będzie przypisany 1 element ApplicationUsers z rolą "sprzedawcy"
  2. Do elementu Customers może być przypisanych wiele elementów ApplicationUsers z rolą "klienci"
  3. Do elementu Customers może być przypisanych wiele elementów ApplicationUsers z rolą "serwisanci"
    Nie mam pojęcia jak to ugryźć. Moje próby kończą się na błędzie podczas add-migration
public class CustomerModel
    {
        public Guid Id { get; set; }
        public string CompanyName { get; set; }
        public virtual ICollection<ApplicationUser> Clients { get; set; }
        public virtual ICollection<ApplicationUser> Servisants { get; set; }
        public Guid? MerchantId { get; set; }
        public virtual ApplicationUser Merchant { get; set; }
    }
PM> add-migration update1
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Model[10605]
      There are multiple relationships between 'ApplicationUser' and 'CustomerModel' without configured foreign key properties. This will cause Entity Framework to create shadow properties on 'ApplicationUser' with names dependent on the discovery order.
An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy.
To undo this action, use Remove-Migration.
PM> 

Mógłbym prosić o podpowiedź?

0

A nie możesz zrobić konkretnych klas tych ról: Client, Servisant, Merchant?

2

Generalnie to EF nie ma pojęcia czym się różnią poszczególne obiekty, dla niego to wszystko mapowanie do jednej tabeli.
Jeśli chcesz to zrobić na kilku tabelach - dodaj po prostu inne nazwy klasy (zamiast ApplicationUser daj ApplicationUserClient albo po prostu Client, Servisants itd.)
Z tego co wiem EF posiada możliwość dodawania do jednej tabeli różnych klas: https://docs.microsoft.com/pl-pl/ef/core/modeling/table-splitting

Jeśli chciałbyś to jednak zrobić w dość prosty sposób to
zrób sobie opcję wiele do wielu public virtual ICollection<ApplicationUser> ApplicationUsers { get; set; }

AplicationUsers posiada po prostu Rolę enum/string (property) "Client, Servisant, Merchant"

I logicznie łączenie użytkownika z klientem, serwisantem i mechanikiem powinno być sprawdzane na poziomie kodu (tak, żeby nie dało się połączyć więcej niż jednego ApplicationUser z rolą Klient do Customera) np. w jakiejś logice dodawania coś w stylu
pseudokod:

public class CustomerModel
private List< ApplicationUser> _applicationUsers; 
public void AssignClient(ApplicationUser client)
{
var currentClientIndex =_applicationUsers.IndexOf(x => x.Role == "Client")
if (currentClientIndex>= 0)
{
_applicationUsers.RemoveAt(currentClientIndex)
}
_applicationUsers.Add(client);
}

Jeśli chcesz to "ograniczyć" na poziomie bazy, to jak wyżej wspomniane - lepiej zrobić osobne obiekty i tabelki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1