Skip to main content

ASP.NET Entity Framework 6.1 – Elenco esaustivo delle Data Annotations

A corredo dei numerosi articoli su EF6 scritti negli ultimi mesi, presentiamo una sintesi dell’ottimo articolo scritto da Julie Lerman e ripreso dal MSDN Data Developer Center, che ha il pregio di presentare in modo ordinato tutte le data annotation messe a disposizione da Entity Framework 6 per corredare le nostre classi in modo da orientare nel modo giusto la generazione della base dati in ottica code-first.

L’approccio code-first, per chi non lo sapesse già, è un metodo di sviluppo che consente di concentrarsi sul domain design, ovvero sulla creazione delle classi che rappresenteranno il nostro model, sfruttando la capacità di Entity Framework di creare automaticamente la struttura dati (il database, per intenderci) necessaria ad ospitarle.

code-first

In questa modalità di sviluppo le Data Annotation rivestono un ruolo fondamentale, in quanto consentono di orientare al meglio la generazione automatica del database definendo una serie di caratteristiche specifiche per ciascuna proprietà delle nostre model classes nel caso in cui le convenzioni normalmente adottate da EF non siano ottimali per i nostri scopi.

Approfondisci

Abilitare e disabilitare il Lazy Loading con Entity Framework

Una delle funzionalità più interessanti dell’Entity Framework è la possibilità di differire il caricamento dei dati negli oggetti di tipo Entity: questa caratteristica, nota come Lazy Loading, consente di alleggerire notevolmente il carico sul Database in quanto le query vengono effettuate soltanto nel momento in cui il codice ha effettivamente bisogno di valorizzare la proprietà richiesta.

Per capire meglio come funziona, prendiamo ad esempio il seguente sistema di classi di tipo Entity:

Approfondisci

Configurare MySQL per poter utilizzare le maiuscole nei nomi delle tabelle

La configurazione predefinita delle versioni Win32 e Win64 di MySQL prevede che i nomi delle tabelle vengano convertiti in minuscolo prima di essere memorizzati su disco. Questa feature può provocare alcune scomodità a chi lavora con strumenti che generano automaticamente codice partendo dall’analisi del DB (Entity Framework, per citare uno tra i più usati), prima tra tutte l’impossibilità di avere delle classi con l’iniziale del nome in maiuscolo o in stile camelCase. Non tutti sanno che per ovviare a questo problema si può ricorrere a una variabile di sistema poco nota da inserire nel file di configurazione di MySQL che consente, per l’appunto, di determinare le modalità di memorizzazione e recupero dei nomi delle tabelle del Database.
Il comando in questione si chiama lower_case_table_names e può essere inserito nel file my.cfg , che solitamente si trova nella cartella:
C:\Program Files (x86)\MySQL\MySQL Server 5.6\
Una volta aperto è sufficiente inserire la variabile sotto la sezione [mysqld] nel seguente modo:

I valori possibili sono:

  • 0: I nomi delle tabelle e dei database vengono memorizzati rispettando le maiuscole/minuscole presenti nell’istruzione CREATE TABLE. La necessità di rispettare le maiuscole/minuscole si estende anche a tutte le query (SELECT * FROM STUDENTS e SELECT * FROM students produrranno risultati diversi in quanto cercheranno tabelle diverse). Questo valore è il predefinito delle versioni MySQL per Linux ma non è adatto per quei sistemi il cui file-system non è case-senstitive (Windows, OSX) in quanto potrebbe comportare alcuni problemi ai file degli indici.
  • 1: I nomi delle tabelle e dei database vengono convertiti in minuscolo (lowercase) prima di essere memorizzati. Questo valore è il predefinito delle versioni MySQL per Windows: il vantaggio rispetto al precedente è che consente una ricerca di tipo case-insensitive (SELECT * FROM STUDENTS e SELECT * FROM students produrranno lo stesso risultato); lo svantaggio è che non è possibile utilizzare le maiuscole, cosa che ci riporta al problema iniziale.
  • 2: I nomi delle tabelle e dei database vengono memorizzati rispettando le maiuscole/minuscole presenti nell’istruzione CREATE TABLE, ma vengono convertiti in minuscolo (lowercase) al momento di risolvere qualsiasi query di ricerca. In buona sostanza questa impostazione è un ibrido delle opzioni 0 e 1 ed è, nella maggior parte dei casi, l’opzione preferibile per i sistemi Windows e OSX in quanto consente di utilizzare le maiuscole nei nomi delle tabelle senza alcuna controindicazione a livello di ricerca.
Per una trattazione più approfondita della variabile di sistema lower_case_table_names suggeriamo di consultare la guida ufficiale di MySQL:

ASP.NET: Creare un sito web MVC5 con Database MySQL, Entity Framework 6 Code-First e Visual Studio 2013

Le nuove potenzialità di EF6 consentono di creare un sito web e relativo data model con poche righe di codice. Sul web esistono numerose guide che illustrano come fare utilizzando SQL Express, ma chi sceglie di utilizzare MySQL troverà senz’altro molto meno materiale. Questa semplice guida risponde a quanti mi hanno chiesto di riassumere i passaggi fondamentali per creare una applicazione web MVC5 configurando EF6 CF con MySQL. Per i primi passaggi mi limiterò a tradurre l’ottimo articolo Getting started with Entity Framework 6 Code First using MVC5 presente sul sito www.asp.net, dal quale prenderò anche alcune immagini a scopo divulgativo.

Questi gli strumenti di cui avremo bisogno (e relativi link alle versioni scaricabili gratuitamente):

Step 1. Creazione di una Web Application

Apriamo Visual Studio 2013 e creiamo un nuovo progetto C# in questo modo:

NP

Nella schermata successiva selezioniamo il template MVC, quindi clicchiamo sul bottone Change Authentication… per decidere se abilitare o meno l’autenticazione utente a seconda delle necessità del sito che vogliamo creare. Nell’esempio che vogliamo fare non ne abbiamo bisogno, quindi possiamo scegliere No Authentication.

CA

Completiamo quindi i passaggi necessari per ultimare la creazione del sito.

Step 2. Installazione di Entity Framework 6

Dal menu Tools (Strumenti, se avete la versione in italiano) selezioniamo Library Package Manager e poi Package Manager Console. Nella console che si aprirà digitiamo il comando seguente:

NuGet si occuperà di installare la versione più recente di Entity Framework (al momento è la 6.1.1). Una volta fatto questo possiamo cominciare a creare le nostre Entities seguendo l’approccio code-first.

Step 3. Creazione delle Entities

Una Entity non è altro che una classe pensata per contenere tutte le informazioni relative a un singolo elemento del nostro Database: prima di creare una o più Entities è quindi necessario avere una idea piuttosto chiara degli elementi di cui avremo bisogno e delle relazioni tra gli stessi che andremo ad impostare. Prendiamo come esempio il più classico degli archivi:

  • un elenco di studenti (Student)
  • che effettuano una o più iscrizioni (Enrollment)
  • a un elenco di corsi (Course).

Spostiamoci quindi all’interno della directory /Models/ (creandola se non esiste) e creiamo le seguenti tre classi:

Step 4. Creazione del Database Context

La classe principale che si occupa di tenere insieme le funzionalità dell’Entity Framework è nota come Database Context. Per crearla è sufficiente estendere la classe di sistema System.Data.Entity.DbContext specificando le Entities da includere nel Data Model. Creiamo quindi una cartella /DAL/ (che sta per Data Access Layer) e aggiungiamo le due classi seguenti:

 

Come si può vedere la classe MyDbContext.cs contiene un DbSet per ogni Entity creata in precedenza. Questo perché, secondo quanto previsto da Entity Framework, a ciascun DbSet corrisponderà una Tabella del nostro Database: le Entities, ovviamente, rappresenteranno le singole righe. Notiamo anche che nel costruttore viene impostato un oggetto di tipo MyDbInitializer, specificato nella classe successiva, che serve a creare il database nel caso in cui non esista e ad inserire tre record di esempio nella tabella Student che verrà creata. E’ possibile derivare il MyDbInitializer da numerose possibili classi di inizializzazione predefinite, come ad esempio:

  1. CreateDatabaseIfNotExists: E’ l’initializer predefinito: come suggerisce il nome, crea il database se questo non esiste: nel caso in cui il modello venga cambiato in modo da non coincidere più con il database esistente questo inizialier lancerà una eccezione. Questo comportamento lo rende ideale per gli ambienti di produzione, meno per gli ambienti di sviluppo dove il Database Model cambia di frequente.
  2. DropCreateDatabaseIfModelChanges: Questo initializer crea un nuovo database, eliminando quello eventualmente già esistente, se una o più classi relative alle Entities risultano modificate rispetto all’ultima inizializzazione. Questo comportamento lo rende ideale per gli ambienti di sviluppo, dove non è solitamente importante mantenere i dati nel DB: è sconsigliato per gli ambienti di produzione in quanto il rischio di data loss è elevato (basta un minimo aggiornamento a una classe Entity per perdere tutto l’archivio).
  3. DropCreateDatabaseAlways: Come suggerisce il nome, questo initializer elimina e ricrea il database ad ogni inizializzazione, ovvero ad ogni avvio dell’applicazione web. Il suo comportamento lo rende ideale per quegli ambienti di sviluppo che necessitano di un refresh continuo dei dati nel database: è ovviamente sconsigliato per gli ambienti di produzione.

IMPORTANTE: come si evince da questo commento, sembra che alcune versioni di Entity Framework richiedano l’utilizzo dell’inizializer DropCreateDatabaseAlways invece di CreateDatabaseIfNotExists quando il metodo sopra descritto viene utilizzato per inizializzare le Migration per la prima volta: in caso contrario, la tabella  _MigrationHistory non verrà creata e alcune cose non funzioneranno, come ad esempio il metodo Seed(). Una volta inizializzate le Migration, sarà possibile passare a un initializer diverso (CreateDatabaseIfNotExistsDropCreateDatabaseIfModelChanges) senza alcun problema.

Notiamo infine che il costruttore della nostra classe contiene un riferimento a una MyDbContextConnectionString che avremo cura di definire nel nostro Web.Config nel corso del prossimo step.

 

Step 5. Collegamento con MySQL

Per collegare la nostra web application al database MySQ abbiamo bisogno del MySQL Connector.NET, scaricabile gratuitamente dal sito web ufficiale oppure tramite NuGet. Una volta collegate le librerie al progetto avremo cura di aggiungere al Web.Config della nostra applicazione una stringa di connessione valida, completa di username e password, in questo modo:

 

Step 6. Avvio dell’applicazione e creazione del Database

Se tutti i passaggi sono stati eseguiti correttamente, l’applicazione provvederà a creare automaticamente il database non appena verrà istanziato un oggetto di tipo MyDbContext.

Questo tipo di inizializzazione può avvenire all’interno di un qualsiasi Controller oppure nel Global.asax sotto forma di proprietà statica centralizzata o in qualsiasi altro punto dell’applicazione, a seconda delle necessità dello sviluppatore e/o del design pattern e/o di eventuali strategie di IoC / UoW adottate. Nel corso di articoli successivi provvederò a fornire esempi più su queste tecniche, sull’utilizzo delle Data Migrations e sulle molte altre potenzialità dell’Entity Framework.

Close