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.
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.cs
aggiornare 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.
Aggiungere la Rating
proprietà ai modelli di visualizzazione , , e Edit.cshtml
rimanentiDelete.cshtml
Create.cshtml
Details.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:
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.
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.
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.
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.cs
aggiornare 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.
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:
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.
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.
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.
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.cs
aggiornare 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.
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:
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.
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.
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.
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.cs
aggiornare 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.
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:
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.
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.
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.
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.cs
aggiornare 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.
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:
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.
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.
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.
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.cs
aggiornare 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.
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:
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.
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.
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.
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.