Mappare le classi di dominio con Entity Framework Code-First

di Stefano Mostarda, in Entity Framework,

Nel precedente articolo abbiamo visto le novità introdotte da Entity Framework 4.1 e come queste migliorino il nostro codice di accesso ai dati. In questo articolo analizzeremo più a fondo quella che certamente è la più grande novità introdotta con Entity Framework 4.1: Code-First. Code-First è la feature che ci permette di mappare le classi di dominio utilizzando solamente il codice ed evitando quindi l'uso del designer di Visual Studio.

Nella prima parte di quest'articolo vedremo come eseguire le operazioni di mapping più basilari come il mapping one-to-one tra una classe ed una tabella, la personalizzazione del mapping ed il mapping delle associazioni tra le classi del modello. Nella seconda parte vedremo una funzionalità di mapping avanzata come il mapping dell'ereditarietà.

Come abbiamo visto nel precedente articolo, abbiamo a disposizione due modi per personalizzare il mapping: DataAnnotation o codice. Le DataAnnotationsono molto comode perché permettono di personalizzare il mapping con dei semplici attributi su classi e proprietà. Tuttavia, le DataAnnotation"sporcano" le classi di dominio che in realtà dovrebbero contenere solo codice di business e non codice di mapping. Se questo non rappresenta un problema (e se si possono modificare le classi di dominio), si possono tranquillamente utilizzare le DataAnnotation, altrimenti si deve ricorrere al codice. Inoltre le DataAnnotation non coprono tutte le possibilità di mapping e quindi in alcuni siamo costretti a ricorrere al codice. Quando possibile, nell'articolo verranno illustrate entrambe le tecniche, li dove le DataAnnotation non coprono la funzionalità necessaria, ricorreremo al codice.

Creare le classi di dominio

Creare le classi di dominio via codice è un'operazione estremamente semplice. Nel caso in cui una classe abbia lo stesso nome della tabella verso cui è mappata e nel caso in cui le proprietà della classe abbiano lo stesso nome delle rispettive colonne della tabella, non dobbiamo fare assolutamentenulla se non scrivere il codice della classe. Prendiamo come esempio la seguente classe di dominio:

public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal UnitPrice { get; set; }
}

e la seguente classe di contesto:

public class AppContext : DbContext
{
  public DbSet<Product> Products { get; set; }
}

Se sul database esiste una tabella che si chiama Products (il nome dell'entity set esposto dal contesto) le cui colonne hanno gli stessi nomi delle proprietà della classe Product, il codice appena visto è tutto ciò di cui abbiamo bisogno per mappare la classe verso la tabella.

Per convenzione, se la classe contiene una proprietà di nome Id o Key oppure il cui nome corrisponde al formato <NomeClasse>Id o<NomeClasse>Key, questa proprietà diventa automaticamente la chiave primaria. Inoltre, se la chiave è di tipo numerico, questa viene automaticamente trattata come un Identity e quindi Entity Framework si aspetta che il suo valore sia calcolato dal database.

Grazie a queste convenzioni (il nome della tabella corrisponde al nome dell'entity set, la chiave primaria ha un nome preciso, le proprietà della classe hanno lo stesso nome delle colonne), il codice che dobbiamo scrivere per eseguire il mapping è veramente minimo.

Nel proseguio dell'articolo utilizzeremo un dominio composto da più classi ed il cui design è mostrato nella figura 1.

Questo dominio mappa sulle tabelle esposte nella figura 2.

Come possiamo vedere, tra le classi di dominio e le tabelle del database ci sono alcune differenze:

  • le classi Customer e GoldCustomer (GoldCustomer eredita da Customer) mentre nel database abbiamo una tabella Customers che contiene i dati per entrambe le classi.
  • Nel dominio esiste il complex type AddressInfo che non ha una controparte in nessuna tabella.
  • Le classi Customer e Order hanno rispettivamente la proprietà Address e ShippingAddress che sono delle complex property di tipo AddressInfo, mentre le tabelle Customer e Orders hanno i campi direttamente nella tabella.
  • La tabella Customer ha una colonna Type che specifica se la riga contiene i dati di un'istanza di un Customer o di un GoldCustomer.
  • La classe OrderDetail mappa sulla tabella Details. Inoltre, La classe OrderDetail ha una proprietà Total che rappresenta il risultato della moltiplicazione della proprietà Quantity con la proprietà UnitPrice e che non ha una controparte nel database. Infine, la foreign key property tra OrderDetail e Product si chiama ProdId, mentre sul database la colonna si chiama ProductId

Prima di vedere come eseguire il mapping tra le varie classi, vediamo come sfruttare le convenzioni di default di Entity Framework Code-First.

3 pagine in totale: 1 2 3
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti