Sto utilizzando EntityFramework Core, Code First e Fluent Api per definire il database dei modelli, e ho seguito la situazione sulla strategia dell'ereditarietà delle mappe:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class User : Person
{
public string UserName { get; set; }
public string Password { get; set; }
}
public class Employee : Person
{
public decimal Salary { get; set; }
}
public class Customer:Person
{
public long DiscountPoints { get; set; }
}
Affari logici
In questo caso, gli utenti, i dipendenti e i clienti sono persone, tuttavia dipendenti e clienti sono anche utenti, così come i dipendenti possono diventare clienti. E ogni tipo è usato in contesti distinti di appicazione.
Ho implementato questo modo per non usare inutilmente valori da altri contesti applicativi.
Domande:
Quali sono le migliori pratiche per mappare un modello di database? Tipo per gerarchia o tabella per tipo? Considerando che per molti, il TPT è generalmente un anti-modello e si traduce in problemi di prestazioni significativi in seguito. in base ai numeri EF 2266
un. Se TPH, come utilizzare il campo discriminatore per molti tipi?
b. Se TPT, come utilizzare questa strategia in EF Core 1.0?
grazie per la vostra attenzione e collaborazione
Ho esaminato brevemente questo aspetto quando ho suonato con il core EF, essendo stato utilizzato per EF6 e ampiamente utilizzato table-per-type.
1a) La mia esperienza è che i mapping predefiniti funzionano abbastanza bene se si aggiunge solo ogni tipo di entità come DbSet al proprio contesto. Se necessario, puoi configurarlo nell'override di OnModelBuilding nel tuo DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasDiscriminator<string>("person_type")
.HasValue<Employee>("employee")
.HasValue<Customer>("customer");
}
1b) Al momento non è possibile utilizzare TPT con core EF. È previsto per le versioni future ed è attualmente elencato come ad alta priorità nella roadmap principale di EF
2) Se utilizziamo rigidi principi DDD, il livello aziendale dovrebbe modellare / rispecchiare il dominio della vita reale il più vicino possibile e non essere influenzato dal livello dati di un'applicazione. Personalmente penso che l'eredità come hai esposto sopra sia un buon specchio di una situazione di vita reale. Tuttavia, il nucleo centrale di EF sembra essere nel campo "composizione preferenziale rispetto all'ereditarietà", che potrebbe portare a modelli di dominio come:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class User
{
public int Id {get;set;}
public Person Person {get; set;}
public int PersonId {get;set;}
public string UserName { get; set; }
public string Password { get; set; }
}
public class Employee
{
public int Id {get; set;}
public User User {get; set;}
public int UserId {get;set;}
public decimal Salary { get; set; }
}
public class Customer
{
public int Id {get;set;}
public User User {get; set;}
public int UserId {get;set;}
public long DiscountPoints { get; set; }
}
Queste entità sarebbero quindi memorizzate in tabelle separate, con relazioni di tipo "fore-key" tra di esse. Anche la transizione di un dipendente in un cliente implicherebbe la creazione di un nuovo cliente, con la stessa proprietà utente del dipendente, ad es
public void CreateCustomerFromEmployee(int employeeId) {
var employee = context.Employees.Where(e => e.Id == employeeId).SingleOrDefault();
context.Customers.Add(new Customer()
{
UserId = employee.UserId,
DiscountPoints = 0
});
context.SaveChanges();
}