Condividi tramite


Parte 8, aggiungere un nuovo campo a un'app MVC core ASP.NET

Nota

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

Avviso

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 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 9 di questo articolo.

Di Rick Anderson

In questa sezione Migrazioni di Entity Framework viene usato per:

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione del nuovo campo al database.

Quando Entity Framework (EF) viene usato per creare automaticamente un database dalle classi modello:

  • Al database viene aggiunta una tabella per tenere traccia dello schema del database.
  • Il database viene verificato che sia sincronizzato con le classi del modello da cui è stato generato. Se questi elementi non sono sincronizzati, Entity Framework genera un'eccezione. In questo modo è più semplice individuare problemi di incoerenza nel database o nel codice.

Aggiungere una proprietà Rating al modello Movie

Aggiungere una Rating proprietà a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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; }
}

Creare l'app

Premere CTRL+MAIUSC+B

Poiché è stato aggiunto un nuovo campo alla Movie classe, è necessario aggiornare l'elenco di associazioni di proprietà in modo che questa nuova proprietà venga inclusa. In MoviesController.csaggiornare l'attributo [Bind] sia per i Edit Create metodi di azione che per includere la Rating proprietà :

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aggiornare i modelli di vista per visualizzare, creare e modificare la nuova proprietà Rating nella vista del browser.

Modificare il /Views/Movies/Index.cshtml file e aggiungere un Rating campo:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Aggiornare /Views/Movies/Create.cshtml con un Rating campo.

È possibile copiare e incollare il "gruppo di moduli" precedente e aggiornare i campi usando intelliSense. IntelliSense funziona con gli helper tag.

Lo sviluppatore ha digitato la lettera R per il valore dell'attributo asp-for nel secondo elemento etichetta della vista. È stato visualizzato un menu contestuale di IntelliSense che mostra i campi disponibili, tra cui Rating, evidenziato automaticamente nell'elenco. Quando lo sviluppatore fa clic sul campo o preme INVIO sulla tastiera, il valore verrà impostato su Classificazione.

Aggiungere la Rating proprietà ai modelli di visualizzazione , , e Edit.cshtml rimanentiDelete.cshtmlCreate.cshtmlDetails.cshtml.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito viene illustrata una modifica di esempio, ma si apporterà questa modifica per ogni new Movie.

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

L'app non funzionerà finché non si aggiorna il database in modo da includere il nuovo campo. Se viene eseguita a questo punto, viene generato il seguente errore SqlException:

SqlException: Invalid column name 'Rating'.

Questo errore si verifica perché la classe del modello Movie aggiornata è diversa dallo schema della tabella Movie nel database esistente. Nella tabella del database non è presente una colonna Rating.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database in base al nuovo schema di classi del modello. Questo approccio è molto utile nelle prime fasi del ciclo di sviluppo in una fase attiva dello sviluppo di un database di test e consente di migliorare rapidamente lo schema del modello e il database insieme. Lo svantaggio è che si perdono i dati esistenti nel database e non è quindi possibile usare questo approccio in un database di produzione. Un modo efficace per sviluppare un'applicazione consiste nell'inizializzare automaticamente un database con dati di test usando un inizializzatore. Questo è un approccio ottimale per le fasi iniziali dello sviluppo e quando si usa SQLite.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio è che i dati vengono mantenuti. È possibile apportare questa modifica manualmente o creando uno script di modifica del database.

  3. Usare Migrazioni di Entity Framework per aggiornare lo schema del database.

Per questa esercitazione, vengono usate le migrazioni di Entity Framework.

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

Menu della Console di Gestione pacchetti

Nella Console di Gestione pacchetti immettere il comando seguente:

Add-Migration Rating

Il comando Add-Migration indica al framework di migrazione di esaminare il modello Movie corrente con lo schema di database Movie corrente e creare il codice necessario per migrare il database nel 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.

Se vengono eliminati tutti i record del database, il database viene inizializzato dal metodo di inizializzazione e viene incluso il campo Rating.

Nella Console di Gestione pacchetti immettere il comando seguente:

Update-Database

Il comando Update-Database esegue il metodo Up nelle migrazioni che non sono state applicate.

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo.

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

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione del nuovo campo al database.

Quando si usa EF Code First per creare automaticamente un database, Code First:

  • Aggiunge una tabella al database per rilevare lo schema del database.
  • Verifica che il database sia sincronizzato con le classi del modello dalle quali è stato generato. Se questi elementi non sono sincronizzati, Entity Framework genera un'eccezione. In questo modo è più semplice individuare problemi di incoerenza nel database o nel codice.

Aggiungere una proprietà Rating al modello Movie

Aggiungere una Rating proprietà a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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; }
}

Creare l'app

Premere CTRL+MAIUSC+B

Poiché è stato aggiunto un nuovo campo alla Movie classe, è necessario aggiornare l'elenco di associazioni di proprietà in modo che questa nuova proprietà venga inclusa. In MoviesController.csaggiornare l'attributo [Bind] sia per i Edit Create metodi di azione che per includere la Rating proprietà :

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aggiornare i modelli di vista per visualizzare, creare e modificare la nuova proprietà Rating nella vista del browser.

Modificare il /Views/Movies/Index.cshtml file e aggiungere un Rating campo:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Aggiornare /Views/Movies/Create.cshtml con un Rating campo.

È possibile copiare e incollare il "gruppo di moduli" precedente e aggiornare i campi usando intelliSense. IntelliSense funziona con gli helper tag.

Lo sviluppatore ha digitato la lettera R per il valore dell'attributo asp-for nel secondo elemento etichetta della vista. È stato visualizzato un menu contestuale di IntelliSense che mostra i campi disponibili, tra cui Rating, evidenziato automaticamente nell'elenco. Quando lo sviluppatore fa clic sul campo o preme INVIO sulla tastiera, il valore verrà impostato su Classificazione.

Aggiornare i modelli rimanenti.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito viene illustrata una modifica di esempio, ma si apporterà questa modifica per ogni new Movie.

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

L'app non funzionerà finché non si aggiorna il database in modo da includere il nuovo campo. Se viene eseguita a questo punto, viene generato il seguente errore SqlException:

SqlException: Invalid column name 'Rating'.

Questo errore si verifica perché la classe del modello Movie aggiornata è diversa dallo schema della tabella Movie nel database esistente. Nella tabella del database non è presente una colonna Rating.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database in base al nuovo schema di classi del modello. Questo approccio è molto utile nelle prime fasi del ciclo di sviluppo in una fase attiva dello sviluppo di un database di test e consente di migliorare rapidamente lo schema del modello e il database insieme. Lo svantaggio è che si perdono i dati esistenti nel database e non è quindi possibile usare questo approccio in un database di produzione. Un modo efficace per sviluppare un'applicazione consiste nell'inizializzare automaticamente un database con dati di test usando un inizializzatore. Questo è un approccio ottimale per le fasi iniziali dello sviluppo e quando si usa SQLite.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio è che i dati vengono mantenuti. È possibile 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 viene usato Migrazioni Code First.

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

Menu della Console di Gestione pacchetti

Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration Rating
Update-Database

Il comando Add-Migration indica al framework di migrazione di esaminare il modello Movie corrente con lo schema di database Movie corrente e creare il codice necessario per migrare il database nel 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.

Se vengono eliminati tutti i record del database, il database viene inizializzato dal metodo di inizializzazione e viene incluso il campo Rating.

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo.

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

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione del nuovo campo al database.

Quando si usa EF Code First per creare automaticamente un database, Code First:

  • Aggiunge una tabella al database per rilevare lo schema del database.
  • Verifica che il database sia sincronizzato con le classi del modello dalle quali è stato generato. Se questi elementi non sono sincronizzati, Entity Framework genera un'eccezione. In questo modo è più semplice individuare problemi di incoerenza nel database o nel codice.

Aggiungere una proprietà Rating al modello Movie

Aggiungere una Rating proprietà a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models;

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; }
}

Creare l'app

Premere CTRL+MAIUSC+B

Poiché è stato aggiunto un nuovo campo alla Movie classe, è necessario aggiornare l'elenco di associazioni di proprietà in modo che questa nuova proprietà venga inclusa. In MoviesController.csaggiornare l'attributo [Bind] sia per i Edit Create metodi di azione che per includere la Rating proprietà :

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aggiornare i modelli di vista per visualizzare, creare e modificare la nuova proprietà Rating nella vista del browser.

Modificare il /Views/Movies/Index.cshtml file e aggiungere un Rating campo:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies![0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies!)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Aggiornare /Views/Movies/Create.cshtml con un Rating campo.

È possibile copiare e incollare il "gruppo di moduli" precedente e aggiornare i campi usando intelliSense. IntelliSense funziona con gli helper tag.

Lo sviluppatore ha digitato la lettera R per il valore dell'attributo asp-for nel secondo elemento etichetta della vista. È stato visualizzato un menu contestuale di IntelliSense che mostra i campi disponibili, tra cui Rating, evidenziato automaticamente nell'elenco. Quando lo sviluppatore fa clic sul campo o preme INVIO sulla tastiera, il valore verrà impostato su Classificazione.

Aggiornare i modelli rimanenti.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito viene illustrata una modifica di esempio, ma si apporterà questa modifica per ogni new Movie.

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

L'app non funzionerà finché non si aggiorna il database in modo da includere il nuovo campo. Se viene eseguita a questo punto, viene generato il seguente errore SqlException:

SqlException: Invalid column name 'Rating'.

Questo errore si verifica perché la classe del modello Movie aggiornata è diversa dallo schema della tabella Movie nel database esistente. Nella tabella del database non è presente una colonna Rating.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database in base al nuovo schema di classi del modello. Questo approccio è molto utile nelle prime fasi del ciclo di sviluppo in una fase attiva dello sviluppo di un database di test e consente di migliorare rapidamente lo schema del modello e il database insieme. Lo svantaggio è che si perdono i dati esistenti nel database e non è quindi possibile usare questo approccio in un database di produzione. Un modo efficace per sviluppare un'applicazione consiste nell'inizializzare automaticamente un database con dati di test usando un inizializzatore. Questo è un approccio ottimale per le fasi iniziali dello sviluppo e quando si usa SQLite.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio è che i dati vengono mantenuti. È possibile 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 viene usato Migrazioni Code First.

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

Menu della Console di Gestione pacchetti

Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration Rating
Update-Database

Il comando Add-Migration indica al framework di migrazione di esaminare il modello Movie corrente con lo schema di database Movie corrente e creare il codice necessario per migrare il database nel 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.

Se vengono eliminati tutti i record del database, il database viene inizializzato dal metodo di inizializzazione e viene incluso il campo Rating.

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo.

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

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione del nuovo campo al database.

Quando si usa EF Code First per creare automaticamente un database, Code First:

  • Aggiunge una tabella al database per rilevare lo schema del database.
  • Verifica che il database sia sincronizzato con le classi del modello dalle quali è stato generato. Se questi elementi non sono sincronizzati, Entity Framework genera un'eccezione. In questo modo è più semplice individuare problemi di incoerenza nel database o nel codice.

Aggiungere una proprietà Rating al modello Movie

Aggiungere una Rating proprietà a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    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; }
    }
}

Creare l'app

CTRL+MAIUSC+B

Poiché è stato aggiunto un nuovo campo alla Movie classe, è necessario aggiornare l'elenco di associazioni di proprietà in modo che questa nuova proprietà venga inclusa. In MoviesController.csaggiornare l'attributo [Bind] sia per i Edit Create metodi di azione che per includere la Rating proprietà :

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aggiornare i modelli di vista per visualizzare, creare e modificare la nuova proprietà Rating nella vista del browser.

Modificare il /Views/Movies/Index.cshtml file e aggiungere un Rating campo:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies)
        {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Aggiornare /Views/Movies/Create.cshtml con un Rating campo.

È possibile copiare e incollare il "gruppo di moduli" precedente e aggiornare i campi usando intelliSense. IntelliSense funziona con gli helper tag.

Lo sviluppatore ha digitato la lettera R per il valore dell'attributo asp-for nel secondo elemento etichetta della vista. È stato visualizzato un menu contestuale di IntelliSense che mostra i campi disponibili, tra cui Rating, evidenziato automaticamente nell'elenco. Quando lo sviluppatore fa clic sul campo o preme INVIO sulla tastiera, il valore verrà impostato su Classificazione.

Aggiornare i modelli rimanenti.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito viene illustrata una modifica di esempio, ma si apporterà questa modifica per ogni new Movie.

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

L'app non funzionerà finché non si aggiorna il database in modo da includere il nuovo campo. Se viene eseguita a questo punto, viene generato il seguente errore SqlException:

SqlException: Invalid column name 'Rating'.

Questo errore si verifica perché la classe del modello Movie aggiornata è diversa dallo schema della tabella Movie nel database esistente. Nella tabella del database non è presente una colonna Rating.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database in base al nuovo schema di classi del modello. Questo approccio è molto utile nelle prime fasi del ciclo di sviluppo in una fase attiva dello sviluppo di un database di test e consente di migliorare rapidamente lo schema del modello e il database insieme. Lo svantaggio è che si perdono i dati esistenti nel database e non è quindi possibile usare questo approccio in un database di produzione. Un modo efficace per sviluppare un'applicazione consiste nell'inizializzare automaticamente un database con dati di test usando un inizializzatore. Questo è un approccio ottimale per le fasi iniziali dello sviluppo e quando si usa SQLite.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio è che i dati vengono mantenuti. È possibile 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 viene usato Migrazioni Code First.

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

Menu della Console di Gestione pacchetti

Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration Rating
Update-Database

Il comando Add-Migration indica al framework di migrazione di esaminare il modello Movie corrente con lo schema di database Movie corrente e creare il codice necessario per migrare il database nel 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.

Se vengono eliminati tutti i record del database, il database viene inizializzato dal metodo di inizializzazione e viene incluso il campo Rating.

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo.

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

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione del nuovo campo al database.

Quando si usa EF Code First per creare automaticamente un database, Code First:

  • Aggiunge una tabella al database per rilevare lo schema del database.
  • Verifica che il database sia sincronizzato con le classi del modello dalle quali è stato generato. Se questi elementi non sono sincronizzati, Entity Framework genera un'eccezione. In questo modo è più semplice individuare problemi di incoerenza nel database o nel codice.

Aggiungere una proprietà Rating al modello Movie

Aggiungere una Rating proprietà a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    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; }
    }
}

Creare l'app

CTRL+MAIUSC+B

Poiché è stato aggiunto un nuovo campo alla Movie classe, è necessario aggiornare l'elenco di associazioni di proprietà in modo che questa nuova proprietà venga inclusa. In MoviesController.csaggiornare l'attributo [Bind] sia per i Edit Create metodi di azione che per includere la Rating proprietà :

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aggiornare i modelli di vista per visualizzare, creare e modificare la nuova proprietà Rating nella vista del browser.

Modificare il /Views/Movies/Index.cshtml file e aggiungere un Rating campo:

<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Rating)
        </th>
        <th></th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model.Movies)
    {
        <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>

Aggiornare /Views/Movies/Create.cshtml con un Rating campo.

È possibile copiare e incollare il "gruppo di moduli" precedente e aggiornare i campi usando intelliSense. IntelliSense funziona con gli helper tag.

Lo sviluppatore ha digitato la lettera R per il valore dell'attributo asp-for nel secondo elemento etichetta della vista. È stato visualizzato un menu contestuale di IntelliSense che mostra i campi disponibili, tra cui Rating, evidenziato automaticamente nell'elenco. Quando lo sviluppatore fa clic sul campo o preme INVIO sulla tastiera, il valore verrà impostato su Classificazione.

Aggiornare i modelli rimanenti.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito viene illustrata una modifica di esempio, ma si apporterà questa modifica per ogni new Movie.

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

L'app non funzionerà finché non si aggiorna il database in modo da includere il nuovo campo. Se viene eseguita a questo punto, viene generato il seguente errore SqlException:

SqlException: Invalid column name 'Rating'.

Questo errore si verifica perché la classe del modello Movie aggiornata è diversa dallo schema della tabella Movie nel database esistente. Nella tabella del database non è presente una colonna Rating.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database in base al nuovo schema di classi del modello. Questo approccio è molto utile nelle prime fasi del ciclo di sviluppo in una fase attiva dello sviluppo di un database di test e consente di migliorare rapidamente lo schema del modello e il database insieme. Lo svantaggio è che si perdono i dati esistenti nel database e non è quindi possibile usare questo approccio in un database di produzione. Un modo efficace per sviluppare un'applicazione consiste nell'inizializzare automaticamente un database con dati di test usando un inizializzatore. Questo è un approccio ottimale per le fasi iniziali dello sviluppo e quando si usa SQLite.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio è che i dati vengono mantenuti. È possibile 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 viene usato Migrazioni Code First.

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

Menu della Console di Gestione pacchetti

Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration Rating
Update-Database

Il comando Add-Migration indica al framework di migrazione di esaminare il modello Movie corrente con lo schema di database Movie corrente e creare il codice necessario per migrare il database nel 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.

Se vengono eliminati tutti i record del database, il database viene inizializzato dal metodo di inizializzazione e viene incluso il campo Rating.

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo.

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

  • Aggiungere un nuovo campo al modello.
  • Eseguire la migrazione del nuovo campo al database.

Quando si usa EF Code First per creare automaticamente un database, Code First:

  • Aggiunge una tabella al database per rilevare lo schema del database.
  • Verifica che il database sia sincronizzato con le classi del modello dalle quali è stato generato. Se questi elementi non sono sincronizzati, Entity Framework genera un'eccezione. In questo modo è più semplice individuare problemi di incoerenza nel database o nel codice.

Aggiungere una proprietà Rating al modello Movie

Aggiungere una Rating proprietà a Models/Movie.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcMovie.Models
{
    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; }
    }
}

Creare l'app

CTRL+MAIUSC+B

Poiché è stato aggiunto un nuovo campo alla Movie classe, è necessario aggiornare l'elenco di associazioni di proprietà in modo che questa nuova proprietà venga inclusa. In MoviesController.csaggiornare l'attributo [Bind] sia per i Edit Create metodi di azione che per includere la Rating proprietà :

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aggiornare i modelli di vista per visualizzare, creare e modificare la nuova proprietà Rating nella vista del browser.

Modificare il /Views/Movies/Index.cshtml file e aggiungere un Rating campo:

<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Movies[0].Rating)
        </th>
        <th></th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model.Movies)
    {
        <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>

Aggiornare /Views/Movies/Create.cshtml con un Rating campo.

È possibile copiare e incollare il "gruppo di moduli" precedente e aggiornare i campi usando intelliSense. IntelliSense funziona con gli helper tag.

Lo sviluppatore ha digitato la lettera R per il valore dell'attributo asp-for nel secondo elemento etichetta della vista. È stato visualizzato un menu contestuale di IntelliSense che mostra i campi disponibili, tra cui Rating, evidenziato automaticamente nell'elenco. Quando lo sviluppatore fa clic sul campo o preme INVIO sulla tastiera, il valore verrà impostato su Classificazione.

Aggiornare i modelli rimanenti.

Aggiornare la classe SeedData in modo che fornisca un valore per la nuova colonna. Di seguito viene illustrata una modifica di esempio, ma si apporterà questa modifica per ogni new Movie.

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

L'app non funzionerà finché non si aggiorna il database in modo da includere il nuovo campo. Se viene eseguita a questo punto, viene generato il seguente errore SqlException:

SqlException: Invalid column name 'Rating'.

Questo errore si verifica perché la classe del modello Movie aggiornata è diversa dallo schema della tabella Movie nel database esistente. Nella tabella del database non è presente una colonna Rating.

Per correggere questo errore, esistono alcuni approcci:

  1. Fare in modo che Entity Framework elimini e crei di nuovo automaticamente il database in base al nuovo schema di classi del modello. Questo approccio è molto utile nelle prime fasi del ciclo di sviluppo in una fase attiva dello sviluppo di un database di test e consente di migliorare rapidamente lo schema del modello e il database insieme. Lo svantaggio è che si perdono i dati esistenti nel database e non è quindi possibile usare questo approccio in un database di produzione. Un modo efficace per sviluppare un'applicazione consiste nell'inizializzare automaticamente un database con dati di test usando un inizializzatore. Questo è un approccio ottimale per le fasi iniziali dello sviluppo e quando si usa SQLite.

  2. Modificare esplicitamente lo schema del database esistente in modo che corrisponda alle classi del modello. Il vantaggio di questo approccio è che i dati vengono mantenuti. È possibile 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 viene usato Migrazioni Code First.

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

Menu della Console di Gestione pacchetti

Nella Console di Gestione pacchetti immettere i comandi seguenti:

Add-Migration Rating
Update-Database

Il comando Add-Migration indica al framework di migrazione di esaminare il modello Movie corrente con lo schema di database Movie corrente e creare il codice necessario per migrare il database nel 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.

Se vengono eliminati tutti i record del database, il database viene inizializzato dal metodo di inizializzazione e viene incluso il campo Rating.

Eseguire l'app e verificare che sia possibile creare, modificare e visualizzare film con un Rating campo.