Le novità di Entity Framework 6 per Code First

di , in LINQ,

Nel precedente articolo abbiamo introdotto le principali novità di Entity Framework 6 e abbiamo visto come queste semplificano lo sviluppo. In questo articolo entriamo più nel dettaglio e analizziamo le novità specifiche di Code First.

Questa nuova versione introduce molte novità per quanto riguarda Code-First. Innanzitutto abbiamo finalmente la possibilità di creare convenzioni (funzionalità che abbiamo introdotto nel precedente articolo). Poi abbiamo anche la possibilità di specificare uno schema del database diverso da quello di default (ad esempio dbo per Sql Server), la possibilità di lanciare script di migrazione custom, la possibilità di personalizzare la tabella che mantiene la storia delle migrazioni di Code First Migrations e infine la possibilità di creare operazioni personalizzate da lanciare insieme ad una migrazione.

Cominciamo ora col vedere queste funzionalità in dettaglio.

Convenzioni custom in Code First

Come visto nel precedente articolo, Entity Framework permette di creare convenzioni custom oltre a quelle già presenti di default. Questo torna utile quando vogliamo utilizzare nostre convenzioni per specificare il mapping all'interno di un modello. Per esempio, Entity Frmamework considera come chiave la proprietà che si chiama Id o che si chiama {NomeTipo}Id. Volendo, possiamo agiungere una convenzione che identifica come chiave anche le proprietà il cui nome segue il pattern Id{NomeTipo}.

Per fare questo possiamo ci basta eseguire l'override del metodo OnModelCreating della classe di contesto ed aggiungere il codice di mapping così come mostrato nel prossimo esempio.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  var prop = modelBuilder.Properties().Where(p => p.Name.Equals("Id" + 
    p.DeclaringType.Name, StringComparison.OrdinalIgnoreCase));
  prop.Configure(p => p.IsKey());
  prop.Configure(p => 
    p.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity));
}

Attraverso il metodo Properties di DbModelBuilder possiamo recuperare tutte le proprietà delle classi del model. In seguito filtriamo le proprietà scegliendo quelle che iniziano con Id seguito dal nome della classe. Una volta ottenuta la lista di queste proprietà impostiamo che queste sono chiave primaria e sono identity sul database.

In alternativa a questa tecnica, possiamo anche creare una classe che possiamo riutilizzare anche in altri progetti. Una classe che genera una convenzione custom dobbiamo deve ereditare dalla classe Convention e deve definire la convenzione all'interno del costruttore. Nel prossimo esempio vediamo come stabilire la stessa convenzione vista in precedenza sfruttando una classe.

public class KeyConvention : Convention
{
  public DecimalConvention()
  {
    var prop = Properties().Where(p => p.Name.Equals("Id" + p.DeclaringType.Name, 
      StringComparison.OrdinalIgnoreCase));
    prop.Configure(p => p.IsKey());
    prop.Configure(p => 
      p.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity));
  }
}

Una volta creata la classe, dobbiamo aggiungerla al contesto sfruttando la collezione Convention della classe DbModelBuiler come mostrato nel prossimo codice

modelBuilder.Conventions.Add<KeyConvention>();

Un ultima modalità per creare una convenzione è specificando il tipo a cui applicarla. Ad esempio, possiamo stabilire che i tipi decimali non siano con una precisione di 18,2 (valore di default) ma di 9,2. Per fare questo ci basta usare la seguente linea di codice nel metodo OnModelCreating del contesto.

modelBuilder.Properties<decimal>()
  .Configure(config => config.HasPrecision(9, 2));

Come si può vedere, passando tramite generics il tipo, possiamo stabilire i valori di default.

Un altro modo per aggiungere convenzioni è quello di creare classi che ereditano da EntityTypeConfiguration e che definiscono il mapping di un'intera classe. Queste classi possono essere aggiunte al context tramite il metodo Conventions.Add. Quanto tuttavia sono molte classi nel nostro modello, il rischio è quello di dover scrivere anche molto codice (ripetitivo e banale) per aggiungerle tutte al contesto. Per eliminare questo problema, possiamo caricare tutte le classi che ereditano da EntityTypeConfiguration tramite la chiamata a un singolo metodo: AddFromAssembly. Nel prossimo esempio vediamo come utilizzare questo metodo per caricare tutte le convenzioni che si trovano nell'assembly attualmetn in esecuzione.

modelBuilder.Configurations.AddFromAssembly(
  Assembly.GetExecutingAssembly());

E' da sottolineare che il metodo AddFromAssembly è una delle funzionalità aggiunte non dal team di ADO.NET, bensì da un membro della community: Unai Zorrilla. Potete trovare maggiori informazioni su questo metodo al seguente link al suo blog: http://www.campusmvp.net/blog/ef-6-setting-configurations-automatically.

Definire uno schema del database

Fino ad Entity Framwork 5, non c'era modo di specificare uno schema del database che fosse diverso da quello di default (dbo per Sql Server) a meno che non si usasse l'API di mapping ToTable per specificare il nome intero della tabella (per intero si intende il nome dello schema e il nome della tabella). Lo svantaggio di quest0approccio è che si deve specificare nel mapping il nome intero per ogni tabella del database. A partire da Entity Framework 6 abbiamo a disposizone un nuovo metodo che ci permette di specificare lo schema in un posto unico per tutte le tabelle: HasDefaultSchema. Nel prossimo esempio mostriamo come utilizzare questo metodo:

modelBuilder.HasDefaultSchema("MySchema");

Il risultato è che quando andiamo a eseguire una qualunque operazione sul database, il codice SQL generato è qualcosa di simile a quello che vediamo qui sotto.

Update MySchema.MyTable set MyColumn = 10;

Come possiamo vedere, il nome della tabella è preceduto dallo schema che abbiamo impostato tramite il metodo HasDefaultSchema.

2 pagine in totale: 1 2
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

Le novità di Entity Framework 6 per Code First 1010 4
| Condividi su: Twitter, Facebook, LinkedIn, Google+

Per inserire un commento, devi avere un account.

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

Approfondimenti