Freeteo


Pensieri e C#dice di Matteo Raumer

Entity Framework Code-First: Ereditare da un oggetto base per campi comuni a più tabelle

Entity Framework 4.1 è sicuramente un passo avanti nel pacchetto, ma per quanto mi riguarda Code-First è finalmente qualcosa che si avvicina al mio modo di approcciare l'applicazione.
Mi piace scrivere codice e mi piace non essere troppo legato al database, non tanto perchè mi capiti spesso di cambiarlo (sinceramente quasi mai) più che altro per avere controllo completo su tutti gli strati, in particolare quello delle entità che chiaramente è trasversale a tutti gli altri.
In particolare sebbene mi trovo ad avere già il database nel progetto che sto sviluppando (di cui tral'altro non potevo cambiare più di tanto perchè utilizzato da precedenti applicazioni) ho trovato molto utile partire ugualmente dal codice per modellare "più pulito".
 
Inoltre fino ad oggi ho sempre sofferto il fatto di non riuscire a far ereditare la maggior parte degli oggetti da un OggettoBase come oggetto e basta, senza dover avere situazioni come Table per Hierarchy (TPH), Table per Type (TPT), Table per Concrete class (TPC) legate cmq al database:
più banalmente, volevo dare a tutte una proprietà "Id" (per me non può esistere nessun oggetto privo di un Id...) e dei campi di sistema "ModificaData", "ModificaUtente" (presenti in tutte le tabelle del database) impostati in un unico punto, e non "copiati" su tutte le varie entità.
 
Con linq2sql o EF < 4.1 non ero ancora in grado di farlo, ora finalmente posso fare in questo modo:
- Definire un OggettoBase con le proprietà (che specifica già il mapping sui campi):

public class OggettoBase
{
   [
DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   [Column("ID")]
   public int ID { get; set; }

   [Column("ModificaData")]
   public DateTime? SYSData { get; set; }

   [Column("ModificaUtente")]
   public string SYSUtente { get; set; }

}


- Definire l'entità che eredita dall'OggettoBase

public class Cliente : OggettoBase
{
   public string Nominativo { get; set; }
   public string CodiceFiscale { get; set; }
}


 

- Definire la mappatura della classe che eredita, da notare che non c'è riferimento alla classe OggettoBase, mentre il MapInheritedProperties va messo prima del ToTable(...) di modo che vengano fatte le mappature anche dell'oggetto base:

class ClienteMapping : EntityTypeConfiguration<Cliente>
{
   public ClienteMapping()
  
{
      //--- non necessario, vedi update più in basso
      //--- Map(x => x.MapInheritedProperties());

      //--- imposto la tabella relativa all'oggetto
      ToTable(
"CLIENTI");

      //--- questa proprità ha un campo diverso dal nome della proprieta
      Property(x => x.CodiceFiscale).HasColumnName("CodFisc");

      //--- il resto delle proprietà non serve perchè hanno lo stesso nome
   }
}

* UPDATE: Come segnalato da Tony Pierascenzi la chiamata al metodo "MapInheritedProperties" non è necessaria in questo caso, lo fa direttamente per noi il runtime di Entity Framework.


- Ed infine il nostro DbContext:

public
class ApplicazioneContext : DbContext
{
   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
      //--- mapping
      modelBuilder.Configurations.Add(new ClienteMapping());

      //--- fine
      base.OnModelCreating(modelBuilder);
   }


   public DbSet<Cliente> Clienti { get; set; }
}



Oltre alla comodità e la pulizia del codice, rimane un obbiettivo raggiunto perchè come è facile intuire, da amante del codice, mi dava proprio fastidio non riuscire a fare una cosa così banale come ereditare da un oggetto base...

In allegato il progetto d'esempio: http://dotnethell.it/users/files/1622_EF.CodeFirst.zip

Categoria: .net
lunedì, 27 giu 2011 Ore. 22.32





  • Views Home Page: 243.506
  • Views Posts: 421.016
  • Views Gallerie: 566.658
  • n° Posts: 163
  • n° Commenti: 148
Anno 2014

Anno 2013

Anno 2012

Anno 2011

Anno 2010

Anno 2009

Anno 2008

Anno 2007

Anno 2006

Anno 2005
Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003