Skip to main content

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.

RELATED POSTS
 

Ryan

IT Project Manager, Web Interface Architect e Lead Developer di numerosi siti e servizi web ad alto traffico in Italia e in Europa. Dal 2010 si occupa anche della progettazione di App e giochi per dispositivi Android, iOS e Mobile Phone per conto di numerose società italiane.

  • Francesco Saverio

    Eccellente articolo. In relazione ad esso, ed alla stringa di connessione al DB MySql, volevo sapere se è possibile, come nel caso di un DB Sql Server, utilizzare la keyword “AttachDbFilename” per fare in modo di avere il DB all’interno della cartella “App_Data” del Progetto MVC (e.g.: AttachDbFilename=|DataDirectory|ContosoUniversity.mdf;).
    Grazie.
    Francesco.

     
    • Ciao e grazie!

      Purtroppo no: la keyword AttachDbFilename è una caratteristica specifica di LocalDB, una versione ultraleggera di SQL Server che consente di creare e interagire direttamente con DB presenti sul filesystem. MySQL al momento non dà questa possibilità, l’unico modo per accedere ai file MyISAM o InnoDB è tramite il servizio MySQL mediante chiamate TCP/UDP (su 3306 o altra porta custom) o Socket.

      Per maggiori informazioni su LocalDB ti rimando al seguente articolo della KB:
      http://msdn.microsoft.com/en-us/library/hh309441%28v=vs.110%29.aspx

      Qui invece trovi un recente articolo (in inglese) che spiega alcune delle insidie legate all’utilizzo di AttachDbFilename:
      http://blogs.sqlsentry.com/aaronbertrand/bad-habits-attachdbfilename/

      Anche io, come l’autore del post, consiglio di utilizzare una istanza reale di SQL Server quando possibile, limitando l’utilizzo di LocalDB a quegli scenari in cui non c’è modo di connettersi a un DB reale neppure in produzione (es. il classico dominio Aruba acquistato senza DB a parte).

       
      • Francesco Saverio

        Chiaro ed esaustivo.
        Grazie mille!!!
        Francesco.

         
  • Pingback: EntityFramework: come impostare un campo ID autoincrementale - Ryadel.com()