Esercitazione: Parte 5, applicare le migrazioni all'esempio Contoso University

In questa esercitazione si inizia a usare la EF Core funzionalità delle migrazioni per la gestione delle modifiche del modello di dati. Nelle esercitazioni successive si aggiungeranno altre migrazioni quando si modifica il modello di dati.

In questa esercitazione:

  • Ottenere informazioni sulle migrazioni
  • Creare una migrazione iniziale
  • Esaminare i metodi Up e Down
  • Esaminare lo snapshot del modello di dati
  • Applicare la migrazione

Prerequisiti

Informazioni sulle migrazioni

Quando si sviluppa una nuova applicazione, il modello di dati cambia di frequente e, a ogni cambiamento, non è più sincronizzato con il database. La serie di esercitazioni è iniziata con la configurazione di Entity Framework per creare il database se non esiste già. Quindi, ogni volta che si modifica il modello di dati, ovvero si aggiungono, rimuovono, o modificano le classi di entità o si modifica la classe DbContext, è possibile eliminare il database. In seguito EF ne crea uno nuovo corrispondente al modello ed esegue il seeding con dati di test.

Questo metodo che consiste nel mantenere il database sincronizzato con il modello di dati funziona bene fino a quando non si distribuisce l'applicazione nell'ambiente di produzione. Quando l'applicazione è in esecuzione nell'ambiente di produzione in genere archivia dati che devono essere mantenuti ed è necessario evitare di perdere tutto ad ogni modifica, come ad esempio all'aggiunta di una colonna. La EF Core funzionalità Migrazioni risolve questo problema consentendo a Entity Framework di aggiornare lo schema del database anziché creare un nuovo database.

Per usare le migrazioni, è possibile usare la console Gestione pacchetti (PMC) o l'interfaccia della riga di comando. Queste esercitazioni illustrano come usare i comandi dell'interfaccia della riga di comando. Per informazioni sulla Console di Gestione pacchetti, vedere la fine di questa esercitazione.

Eliminare il database

Installare EF Core gli strumenti come strumento globale ed eliminare il database:

dotnet tool install --global dotnet-ef
dotnet ef database drop

Nota

Per impostazione predefinita, l'architettura dei file binari .NET da installare rappresenta l'architettura del sistema operativo attualmente in esecuzione. Per specificare un'architettura del sistema operativo diversa, vedere l'opzione dotnet tool install, --arch. Per altre informazioni, vedere Problema di GitHub dotnet/AspNetCore.Docs #29262.

Nella sezione seguente viene illustrato come eseguire i comandi della CLI.

Creare una migrazione iniziale

Salvare le modifiche e compilare il progetto. Aprire una finestra di comando e passare alla cartella del progetto. Ecco un modo rapido per eseguire questa operazione:

  • In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e scegliere Apri cartella in Esplora File dal menu di scelta rapida.

    Open in File Explorer menu item

  • Immettere "cmd" nella barra degli indirizzi e premere INVIO.

    Open command window

Immettere il comando seguente nella finestra Comando:

dotnet ef migrations add InitialCreate

Nei comandi precedenti viene visualizzato un output simile al seguente:

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core initialized 'SchoolContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Done. To undo this action, use 'ef migrations remove'

Se viene visualizzato un messaggio di errore "Impossibile accedere al file ... ContosoUniversity.dll perché viene usato da un altro processo. Trovare l'icona iis Express nell'area di notifica di Windows e fare clic con il pulsante destro del mouse su di esso, quindi scegliere ContosoUniversity > Stop Site.

Esaminare i metodi Up e Down

Quando è stato eseguito il comando migrations add, EF ha generato il codice che crea il database da zero. Questo codice si trova nella cartella Migrations , nel file denominato <timestamp>_InitialCreate.cs. Il metodo Up della classe InitialCreate crea le tabelle di database che corrispondono ai set di entità del modello di dati, e il metodo Down le elimina, come illustrato nell'esempio seguente.

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Course",
            columns: table => new
            {
                CourseID = table.Column<int>(nullable: false),
                Credits = table.Column<int>(nullable: false),
                Title = table.Column<string>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Course", x => x.CourseID);
            });

        // Additional code not shown
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Enrollment");
        // Additional code not shown
    }
}

Le migrazioni chiamano il metodo Up per implementare le modifiche al modello di dati per una migrazione. Quando si immette un comando per annullare l'aggiornamento, le migrazioni chiamano il metodo Down.

Questo codice è per la migrazione iniziale creata al momento dell'immissione del comando migrations add InitialCreate. Il parametro del nome della migrazione, nell'esempio "InitialCreate", viene usato per il nome del file e può essere ciò che si vuole. È consigliabile scegliere una parola o una frase che riepiloghi cosa viene fatto nella migrazione. Ad esempio, è possibile denominare una migrazione successiva "AddDepartmentTable".

Se la migrazione iniziale è stata creata quando il database esisteva già, il codice di creazione del database viene generato ma non è necessario eseguirlo perché il database corrisponde già al modello di dati. Quando si distribuisce l'app in un altro ambiente in cui il database non esiste ancora, questo codice verrà eseguito per creare il database, è consigliabile quindi testarlo prima. Ecco perché il database è stato eliminato in precedenza, in modo che le migrazioni possano crearne una nuova da zero.

Snapshot del modello di dati

Le migrazioni creano uno snapshot dello schema del database corrente in Migrations/SchoolContextModelSnapshot.cs. Quando si aggiunge una migrazione, EF determina le modifiche apportate confrontando il modello di dati con il file dello snapshot.

Usare il comando dotnet ef migrations remove per rimuovere una migrazione. dotnet ef migrations remove elimina la migrazione e garantisce che lo snapshot venga reimpostato correttamente. In caso dotnet ef migrations remove di errore, usare dotnet ef migrations remove -v per ottenere altre informazioni sull'errore.

Per altre informazioni sull'uso del file di snapshot, vedere EF Core Migrazioni in Ambienti team.

Applicare la migrazione

Nella finestra di comando immettere il comando seguente per creare il database e le tabelle al suo interno.

dotnet ef database update

L'output del comando è simile al comando migrations add, a eccezione del fatto che vengono visualizzati i log per i comandi SQL che configurano il database. La maggior parte dei log viene omessa nell'output di esempio seguente. Se si preferisce non visualizzare questo livello di dettaglio nei messaggi di log, è possibile modificare il livello di log nel appsettings.Development.json file. Per altre informazioni, vedere Registrazione in .NET Core e ASP.NET Core.

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core initialized 'SchoolContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (274ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      CREATE DATABASE [ContosoUniversity2];
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (60ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      IF SERVERPROPERTY('EngineEdition') <> 5
      BEGIN
          ALTER DATABASE [ContosoUniversity2] SET READ_COMMITTED_SNAPSHOT ON;
      END;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (15ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [__EFMigrationsHistory] (
          [MigrationId] nvarchar(150) NOT NULL,
          [ProductVersion] nvarchar(32) NOT NULL,
          CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
      );

<logs omitted for brevity>

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
      VALUES (N'20190327172701_InitialCreate', N'5.0-rtm');
Done.

Per controllare il database come è stato fatto nella prima esercitazione, usare Esplora oggetti di SQL Server. Si noterà l'aggiunta di una tabella __EFMigrationsHistory che tiene traccia di quali migrazioni sono state applicate al database. Visualizzare i dati nella tabella: si noterà la presenza di una riga per la prima migrazione. Nell'ultimo log nell'esempio di output della CLI precedente viene visualizzata l'istruzione INSERT che crea tale riga.

Eseguire l'applicazione per verificare che tutto funzioni come prima.

Students Index page

Interfaccia della riga di comando e console di gestione pacchetto a confronto

Gli strumenti di EF per la gestione delle migrazioni sono disponibili dai comandi della CLI di .NET Core o dai cmdlet di PowerShell in Visual Studio nella finestra Console di Gestione pacchetti. In questa esercitazione viene illustrato come usare la CLI, ma se si preferisce è possibile usare la console di Gestione pacchetti.

I comandi di EF per la console di Gestione pacchetti sono inclusi nel pacchetto Microsoft.EntityFrameworkCore.Tools. Questo pacchetto è incluso nel metapacchetto Microsoft.AspNetCore.App, quindi non è necessario aggiungere un riferimento al pacchetto se l'app dispone di un riferimento al pacchetto per Microsoft.AspNetCore.App.

Importante: questo non è lo stesso pacchetto di quello installato per l'interfaccia della riga di comando modificando il .csproj file. Il nome di questo pacchetto termina con Tools, a differenza del nome del pacchetto della CLI che termina con Tools.DotNet.

Per altre informazioni sui comandi della CLI, vedere Strumenti da riga di comando di EF Core .NET.

Per altre informazioni sui comandi della console di Gestione pacchetti, vedere Console di Gestione pacchetti (Visual Studio).

Ottenere il codice

Scaricare o visualizzare l'applicazione completata.

Passaggio successivo

Passare all'esercitazione successiva per iniziare a esaminare argomenti più avanzati sull'espansione del modello di dati. Lungo il percorso verranno create e applicate altre migrazioni.