Parte 7, aggiungere un nuovo campo a una Razor pagina in ASP.NET Core

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Di Rick Anderson

In questa sezione vengono usate le Migrazioni Code First di Entity Framework per:

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione nel database della modifica al nuovo schema del campo.

Quando si usa Entity Framework Code First per creare e tenere traccia automaticamente di un database, Code First:

  • Aggiunge una __EFMigrationsHistory tabella al database per rilevare se lo schema del database è sincronizzato con le classi del modello da cui è stato generato.
  • Genera un'eccezione se le classi del modello non sono sincronizzate con il database.

La verifica automatica che lo schema e il modello sono sincronizzati semplifica l'individuazione di problemi di codice del database incoerenti.

Aggiunta di una proprietà Rating al modello Movie

  1. Aprire il Models/Movie.cs file e aggiungere una Rating proprietà:

    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Modificare Pages/Movies/Index.cshtmle aggiungere un Rating campo:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Title)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ReleaseDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Genre)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Rating)
                    </td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  3. Aggiornare le pagine seguenti con un Rating campo:

L'app non funzionerà finché il database non viene aggiornato per includere il nuovo campo. L'esecuzione dell'app senza un aggiornamento al database genera un'eccezione SqlException:

SqlException: Invalid column name 'Rating'.

L'eccezione SqlException è causata dalla classe del modello Movie aggiornata diversa dallo schema della tabella Movie del database. Nella tabella di database non è presente alcuna Rating colonna.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database usando il nuovo schema di classi del modello. Questo approccio è utile nelle prime fasi del ciclo di sviluppo, consentendo agli sviluppatori di evolvere rapidamente il modello e lo schema del database insieme. Lo svantaggio è che i dati esistenti nel database andranno persi. Non usare questo approccio in un database di produzione. L'eliminazione del database sulle modifiche dello schema e l'uso di un inizializzatore per eseguire automaticamente il seeding del database con i dati di test è spesso un modo produttivo per sviluppare un'app.
  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio consiste nel mantenere i dati. Apportare questa modifica manualmente o creando uno script di modifica del database.
  3. Usare Migrazioni Code First per aggiornare lo schema del database.

Per questa esercitazione usare Migrazioni Code First.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito è illustrata una modifica di esempio, ma apportare questa modifica per ogni new Movie blocco.

context.Movie.AddRange(
    new Movie
    {
        Title = "When Harry Met Sally",
        ReleaseDate = DateTime.Parse("1989-2-12"),
        Genre = "Romantic Comedy",
        Price = 7.99M,
        Rating = "R"
    },

Vedere il file SeedData.cs completato.

Creare l'app

Premere CTRL+MAIUSC+B

Aggiungere una migrazione per il campo Rating

  1. Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti.

  2. Nella Console di Gestione pacchetti immettere i comandi seguenti:

    Add-Migration Rating
    Update-Database
    

Il comando Add-Migration indica al framework di:

  • Confrontare il Movie modello con lo schema del Movie database.
  • Creare il codice per eseguire la migrazione dello schema del database al nuovo modello.

Il nome "Rating" è arbitrario e viene usato per denominare il file di migrazione. È consigliabile usare un nome significativo per il file di migrazione.

Il Update-Database comando indica al framework di applicare le modifiche dello schema al database e di conservare i dati esistenti.

Eliminare tutti i record nel database, l'inizializzatore eseguirà il seeding del database e includerà il Rating campo . L'eliminazione può essere eseguita con i collegamenti di eliminazione nel browser o da Sql Server Esplora oggetti (SSOX).

Un'altra opzione è quella di eliminare il database e usare le migrazioni per ricreare il database. Per eliminare il database da SSOX:

  1. Selezionare il database in SSOX.

  2. Fare clic con il pulsante destro del mouse sul database e scegliere Elimina.

  3. Selezionare Chiudi connessioni esistenti.

  4. Seleziona OK.

  5. Nella Console di Gestione pacchetti aggiornare il database:

    Update-Database
    

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo. Se il database non è inizializzato, impostare un punto di interruzione nel metodo SeedData.Initialize.

Passaggi successivi

In questa sezione vengono usate le Migrazioni Code First di Entity Framework per:

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione nel database della modifica al nuovo schema del campo.

Quando si usa Entity Framework Code First per creare e tenere traccia automaticamente di un database, Code First:

  • Aggiunge una __EFMigrationsHistory tabella al database per rilevare se lo schema del database è sincronizzato con le classi del modello da cui è stato generato.
  • Genera un'eccezione se le classi del modello non sono sincronizzate con il database.

La verifica automatica che lo schema e il modello sono sincronizzati semplifica l'individuazione di problemi di codice del database incoerenti.

Aggiunta di una proprietà Rating al modello Movie

  1. Aprire il Models/Movie.cs file e aggiungere una Rating proprietà:

    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Modificare Pages/Movies/Index.cshtmle aggiungere un Rating campo:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Title)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ReleaseDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Genre)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Rating)
                    </td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  3. Aggiornare le pagine seguenti con un Rating campo:

L'app non funzionerà finché il database non viene aggiornato per includere il nuovo campo. L'esecuzione dell'app senza un aggiornamento al database genera un'eccezione SqlException:

SqlException: Invalid column name 'Rating'.

L'eccezione SqlException è causata dalla classe del modello Movie aggiornata diversa dallo schema della tabella Movie del database. Nella tabella di database non è presente alcuna Rating colonna.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database usando il nuovo schema di classi del modello. Questo approccio è utile nelle prime fasi del ciclo di sviluppo, consentendo agli sviluppatori di evolvere rapidamente il modello e lo schema del database insieme. Lo svantaggio è che i dati esistenti nel database andranno persi. Non usare questo approccio in un database di produzione. L'eliminazione del database sulle modifiche dello schema e l'uso di un inizializzatore per eseguire automaticamente il seeding del database con i dati di test è spesso un modo produttivo per sviluppare un'app.
  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio consiste nel mantenere i dati. Apportare questa modifica manualmente o creando uno script di modifica del database.
  3. Usare Migrazioni Code First per aggiornare lo schema del database.

Per questa esercitazione usare Migrazioni Code First.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito è illustrata una modifica di esempio, ma apportare questa modifica per ogni new Movie blocco.

context.Movie.AddRange(
    new Movie
    {
        Title = "When Harry Met Sally",
        ReleaseDate = DateTime.Parse("1989-2-12"),
        Genre = "Romantic Comedy",
        Price = 7.99M,
        Rating = "R"
    },

Vedere il file SeedData.cs completato.

Creare l'app

Premere CTRL+MAIUSC+B

Aggiungere una migrazione per il campo Rating

  1. Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti.

  2. Nella Console di Gestione pacchetti immettere i comandi seguenti:

    Add-Migration Rating
    Update-Database
    

Il comando Add-Migration indica al framework di:

  • Confrontare il Movie modello con lo schema del Movie database.
  • Creare il codice per eseguire la migrazione dello schema del database al nuovo modello.

Il nome "Rating" è arbitrario e viene usato per denominare il file di migrazione. È consigliabile usare un nome significativo per il file di migrazione.

Il Update-Database comando indica al framework di applicare le modifiche dello schema al database e di conservare i dati esistenti.

Eliminare tutti i record nel database, l'inizializzatore eseguirà il seeding del database e includerà il Rating campo . L'eliminazione può essere eseguita con i collegamenti di eliminazione nel browser o da Sql Server Esplora oggetti (SSOX).

Un'altra opzione è quella di eliminare il database e usare le migrazioni per ricreare il database. Per eliminare il database da SSOX:

  1. Selezionare il database in SSOX.

  2. Fare clic con il pulsante destro del mouse sul database e scegliere Elimina.

  3. Selezionare Chiudi connessioni esistenti.

  4. Seleziona OK.

  5. Nella Console di Gestione pacchetti aggiornare il database:

    Update-Database
    

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo. Se il database non è inizializzato, impostare un punto di interruzione nel metodo SeedData.Initialize.

Passaggi successivi

In questa sezione vengono usate le Migrazioni Code First di Entity Framework per:

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione nel database della modifica al nuovo schema del campo.

Quando si usa Entity Framework Code First per creare e tenere traccia automaticamente di un database, Code First:

  • Aggiunge una __EFMigrationsHistory tabella al database per rilevare se lo schema del database è sincronizzato con le classi del modello da cui è stato generato.
  • Genera un'eccezione se le classi del modello non sono sincronizzate con il database.

La verifica automatica che lo schema e il modello sono sincronizzati semplifica l'individuazione di problemi di codice del database incoerenti.

Aggiunta di una proprietà Rating al modello Movie

  1. Aprire il Models/Movie.cs file e aggiungere una Rating proprietà:

    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Modificare Pages/Movies/Index.cshtmle aggiungere un Rating campo:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Title)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ReleaseDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Genre)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Rating)
                    </td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  3. Aggiornare le pagine seguenti con un Rating campo:

L'app non funzionerà finché il database non viene aggiornato per includere il nuovo campo. L'esecuzione dell'app senza un aggiornamento al database genera un'eccezione SqlException:

SqlException: Invalid column name 'Rating'.

L'eccezione SqlException è causata dalla classe del modello Movie aggiornata diversa dallo schema della tabella Movie del database. Nella tabella di database non è presente alcuna Rating colonna.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database usando il nuovo schema di classi del modello. Questo approccio è utile nelle prime fasi del ciclo di sviluppo, consentendo agli sviluppatori di evolvere rapidamente il modello e lo schema del database insieme. Lo svantaggio è che i dati esistenti nel database andranno persi. Non usare questo approccio in un database di produzione. L'eliminazione del database sulle modifiche dello schema e l'uso di un inizializzatore per eseguire automaticamente il seeding del database con i dati di test è spesso un modo produttivo per sviluppare un'app.
  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio consiste nel mantenere i dati. Apportare questa modifica manualmente o creando uno script di modifica del database.
  3. Usare Migrazioni Code First per aggiornare lo schema del database.

Per questa esercitazione usare Migrazioni Code First.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito è illustrata una modifica di esempio, ma apportare questa modifica per ogni new Movie blocco.

context.Movie.AddRange(
    new Movie
    {
        Title = "When Harry Met Sally",
        ReleaseDate = DateTime.Parse("1989-2-12"),
        Genre = "Romantic Comedy",
        Price = 7.99M,
        Rating = "R"
    },

Vedere il file SeedData.cs completato.

Compilare la soluzione.

Aggiungere una migrazione per il campo Rating

  1. Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti.

  2. Nella Console di Gestione pacchetti immettere i comandi seguenti:

    Add-Migration Rating
    Update-Database
    

Il comando Add-Migration indica al framework di:

  • Confrontare il Movie modello con lo schema del Movie database.
  • Creare il codice per eseguire la migrazione dello schema del database al nuovo modello.

Il nome "Rating" è arbitrario e viene usato per denominare il file di migrazione. È consigliabile usare un nome significativo per il file di migrazione.

Il Update-Database comando indica al framework di applicare le modifiche dello schema al database e di conservare i dati esistenti.

Eliminare tutti i record nel database, l'inizializzatore eseguirà il seeding del database e includerà il Rating campo . L'eliminazione può essere eseguita con i collegamenti di eliminazione nel browser o da Sql Server Esplora oggetti (SSOX).

Un'altra opzione è quella di eliminare il database e usare le migrazioni per ricreare il database. Per eliminare il database da SSOX:

  1. Selezionare il database in SSOX.

  2. Fare clic con il pulsante destro del mouse sul database e scegliere Elimina.

  3. Selezionare Chiudi connessioni esistenti.

  4. Seleziona OK.

  5. Nella Console di Gestione pacchetti aggiornare il database:

    Update-Database
    

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo. Se il database non è inizializzato, impostare un punto di interruzione nel metodo SeedData.Initialize.

Passaggi successivi

Visualizzare o scaricare il codice di esempio (procedura per il download).

In questa sezione vengono usate le Migrazioni Code First di Entity Framework per:

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione nel database della modifica al nuovo schema del campo.

Quando si usa Code First di Entity Framework per creare automaticamente un database, Code First:

  • Aggiunge una __EFMigrationsHistory tabella al database per rilevare se lo schema del database è sincronizzato con le classi del modello da cui è stato generato.
  • Se le classi del modello non sono sincronizzate con il database, EF genera un'eccezione.

La verifica automatica che lo schema e il modello sono sincronizzati semplifica l'individuazione di problemi di codice del database incoerenti.

Aggiunta di una proprietà Rating al modello Movie

  1. Aprire il Models/Movie.cs file e aggiungere una Rating proprietà:

    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; }
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; }
    }
    
  2. Compilazione dell'app.

  3. Modificare Pages/Movies/Index.cshtmle aggiungere un Rating campo:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Title)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ReleaseDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Genre)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Rating)
                    </td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  4. Aggiornare le pagine seguenti con un Rating campo:

L'app non funzionerà finché il database non viene aggiornato per includere il nuovo campo. L'esecuzione dell'app senza un aggiornamento al database genera un'eccezione SqlException:

SqlException: Invalid column name 'Rating'.

L'eccezione SqlException è causata dalla classe del modello Movie aggiornata diversa dallo schema della tabella Movie del database. Nella tabella di database non è presente alcuna Rating colonna.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database usando il nuovo schema di classi del modello. Questo approccio è utile nelle prime fasi del ciclo di sviluppo, che consente di evolvere rapidamente il modello e lo schema del database insieme. Lo svantaggio è che si perdono i dati esistenti nel database. Non usare questo approccio in un database di produzione. L'eliminazione del database sulle modifiche dello schema e l'uso di un inizializzatore per eseguire automaticamente il seeding del database con i dati di test è spesso un modo produttivo per sviluppare un'app.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio consiste nel mantenere i dati. Apportare questa modifica manualmente o creando uno script di modifica del database.

  3. Usare Migrazioni Code First per aggiornare lo schema del database.

Per questa esercitazione usare Migrazioni Code First.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito è illustrata una modifica di esempio, ma apportare questa modifica per ogni new Movie blocco.

context.Movie.AddRange(
    new Movie
    {
        Title = "When Harry Met Sally",
        ReleaseDate = DateTime.Parse("1989-2-12"),
        Genre = "Romantic Comedy",
        Price = 7.99M,
        Rating = "R"
    },

Vedere il file SeedData.cs completato.

Compilare la soluzione.

Aggiungere una migrazione per il campo Rating

  1. Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti.

  2. Nella Console di Gestione pacchetti immettere i comandi seguenti:

    Add-Migration Rating
    Update-Database
    

Il comando Add-Migration indica al framework di:

  • Confrontare il Movie modello con lo schema del Movie database.
  • Creare il codice per eseguire la migrazione dello schema del database al nuovo modello.

Il nome "Rating" è arbitrario e viene usato per denominare il file di migrazione. È consigliabile usare un nome significativo per il file di migrazione.

Il Update-Database comando indica al framework di applicare le modifiche dello schema al database e di conservare i dati esistenti.

Eliminare tutti i record nel database, l'inizializzatore eseguirà il seeding del database e includerà il Rating campo . L'eliminazione può essere eseguita con i collegamenti di eliminazione nel browser o da Sql Server Esplora oggetti (SSOX).

Un'altra opzione è quella di eliminare il database e usare le migrazioni per ricreare il database. Per eliminare il database da SSOX:

  1. Selezionare il database in SSOX.

  2. Fare clic con il pulsante destro del mouse sul database e scegliere Elimina.

  3. Selezionare Chiudi connessioni esistenti.

  4. Seleziona OK.

  5. Nella Console di Gestione pacchetti aggiornare il database:

    Update-Database
    

Eseguire l'app e verificare che sia possibile creare/modificare/visualizzare i film con un campo Rating. Se il database non è inizializzato, impostare un punto di interruzione nel metodo SeedData.Initialize.

Passaggi successivi

Visualizzare o scaricare il codice di esempio (procedura per il download).

In questa sezione vengono usate le Migrazioni Code First di Entity Framework per:

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione nel database della modifica al nuovo schema del campo.

Quando si usa Code First di Entity Framework per creare automaticamente un database, Code First:

  • Aggiunge una __EFMigrationsHistory tabella al database per rilevare se lo schema del database è sincronizzato con le classi del modello da cui è stato generato.
  • Se le classi del modello non sono sincronizzate con il database, EF genera un'eccezione.

La verifica automatica che lo schema e il modello sono sincronizzati semplifica l'individuazione di problemi di codice del database incoerenti.

Aggiunta di una proprietà Rating al modello Movie

  1. Aprire il Models/Movie.cs file e aggiungere una Rating proprietà:

    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; }
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; }
    }
    
  2. Compilazione dell'app.

  3. Modificare Pages/Movies/Index.cshtmle aggiungere un Rating campo:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
    
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Price)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Movie[0].Rating)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Movie)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Title)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ReleaseDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Genre)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Rating)
                    </td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                        <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                        <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    
  4. Aggiornare le pagine seguenti con un Rating campo:

L'app non funzionerà finché il database non viene aggiornato per includere il nuovo campo. L'esecuzione dell'app senza un aggiornamento al database genera un'eccezione SqlException:

SqlException: Invalid column name 'Rating'.

L'eccezione SqlException è causata dalla classe del modello Movie aggiornata diversa dallo schema della tabella Movie del database. Nella tabella di database non è presente alcuna Rating colonna.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database usando il nuovo schema di classi del modello. Questo approccio è utile nelle prime fasi del ciclo di sviluppo, che consente di evolvere rapidamente il modello e lo schema del database insieme. Lo svantaggio è che si perdono i dati esistenti nel database. Non usare questo approccio in un database di produzione. L'eliminazione del database sulle modifiche dello schema e l'uso di un inizializzatore per eseguire automaticamente il seeding del database con i dati di test è spesso un modo produttivo per sviluppare un'app.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio consiste nel mantenere i dati. Apportare questa modifica manualmente o creando uno script di modifica del database.

  3. Usare Migrazioni Code First per aggiornare lo schema del database.

Per questa esercitazione usare Migrazioni Code First.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito è illustrata una modifica di esempio, ma apportare questa modifica per ogni new Movie blocco.

context.Movie.AddRange(
    new Movie
    {
        Title = "When Harry Met Sally",
        ReleaseDate = DateTime.Parse("1989-2-12"),
        Genre = "Romantic Comedy",
        Price = 7.99M,
        Rating = "R"
    },

Vedere il file SeedData.cs completato.

Compilare la soluzione.

Aggiungere una migrazione per il campo Rating

  1. Scegliere NuGet Gestione pacchetti > console Gestione pacchetti dal menu Strumenti.

  2. Nella Console di Gestione pacchetti immettere i comandi seguenti:

    Add-Migration Rating
    Update-Database
    

Il comando Add-Migration indica al framework di:

  • Confrontare il Movie modello con lo schema del Movie database.
  • Creare il codice per eseguire la migrazione dello schema del database al nuovo modello.

Il nome "Rating" è arbitrario e viene usato per denominare il file di migrazione. È consigliabile usare un nome significativo per il file di migrazione.

Il Update-Database comando indica al framework di applicare le modifiche dello schema al database e di conservare i dati esistenti.

Se si eliminano tutti i record nel database, l'inizializzatore eseguirà il seeding del database e includerà il Rating campo . È possibile eseguire questa operazione con i collegamenti di eliminazione nel browser o da Sql Server Object Explorer (SSOX).

Un'altra opzione è quella di eliminare il database e usare le migrazioni per ricreare il database. Per eliminare il database da SSOX:

  • Selezionare il database in SSOX.

  • Fare clic con il pulsante destro del mouse sul database e scegliere Elimina.

  • Selezionare Chiudi connessioni esistenti.

  • Seleziona OK.

  • Nella Console di Gestione pacchetti aggiornare il database:

    Update-Database
    

Eseguire l'app e verificare che sia possibile creare/modificare/visualizzare i film con un campo Rating. Se il database non è inizializzato, impostare un punto di interruzione nel metodo SeedData.Initialize.

Passaggi successivi