Aggiunta di un nuovo campo al modello di filmato e alla tabella
Nota
Una versione aggiornata di questa esercitazione è disponibile qui che usa ASP.NET MVC 5 e Visual Studio 2013. È più sicuro, molto più semplice da seguire e dimostra più funzionalità.
In questa sezione si userà Migrazioni Code First di Entity Framework per eseguire la migrazione di alcune modifiche alle classi del modello in modo che la modifica venga applicata al database.
Per impostazione predefinita, quando si usa Entity Framework Code First per creare automaticamente un database, come illustrato in precedenza in questa esercitazione, Code First aggiunge una tabella al database per tenere traccia se lo schema del database è sincronizzato con le classi del modello da cui è stato generato. Se non sono sincronizzati, Entity Framework genera un errore. In questo modo è più semplice tenere traccia dei problemi in fase di sviluppo che altrimenti potrebbero essere rilevati solo (da errori oscurati) in fase di esecuzione.
Configurazione di Migrazioni Code First per le modifiche del modello
Se si usa Visual Studio 2012, fare doppio clic sul file Movies.mdf da Esplora soluzioni per aprire lo strumento di database. Visual Studio Express per Web mostrerà Esplora database. Visual Studio 2012 mostrerà Esplora server. Se si usa Visual Studio 2010, usare SQL Server Esplora oggetti.
Nello strumento di database (Esplora database, Esplora server o SQL Server Esplora oggetti), fare clic con il pulsante destro del mouse e MovieDBContext
scegliere Elimina per eliminare il database dei film.
Tornare a Esplora soluzioni. Fare clic con il pulsante destro del mouse sul file Movies.mdf e selezionare Elimina per rimuovere il database dei film.
Compilare l'applicazione e verificare che non siano presenti errori.
Nel menu Strumenti fare clic su Gestione pacchetti NuGet e quindi su Console di Gestione pacchetti.
Nella finestra della console Gestione pacchetti al PM>
prompt immettere "Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext".
Il comando Enable-Migrations (illustrato sopra) crea un file Configuration.cs in una nuova cartella Migrations .
Visual Studio apre il file Configuration.cs . Sostituire il Seed
metodo nel file Configuration.cs con il codice seguente:
protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
context.Movies.AddOrUpdate( i => i.Title,
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Price = 7.99M
},
new Movie
{
Title = "Ghostbusters ",
ReleaseDate = DateTime.Parse("1984-3-13"),
Genre = "Comedy",
Price = 8.99M
},
new Movie
{
Title = "Ghostbusters 2",
ReleaseDate = DateTime.Parse("1986-2-23"),
Genre = "Comedy",
Price = 9.99M
},
new Movie
{
Title = "Rio Bravo",
ReleaseDate = DateTime.Parse("1959-4-15"),
Genre = "Western",
Price = 3.99M
}
);
}
Fare clic con il pulsante destro del mouse sulla linea ondulata rossa sotto Movie
e selezionare Risolvi e quindi usare MvcMovie.Models;
In questo modo viene aggiunta l'istruzione using seguente:
using MvcMovie.Models;
Nota
Migrazioni Code First chiama il Seed
metodo dopo ogni migrazione( ovvero la chiamata di update-database nella console di Gestione pacchetti) e questo metodo aggiorna le righe già inserite o le inserisce se non esistono ancora.
Premere CTRL-MAIUSC-B per compilare il progetto.Se non si esegue la compilazione a questo punto, la procedura seguente avrà esito negativo.
Il passaggio successivo consiste nel creare una DbMigration
classe per la migrazione iniziale. Questa migrazione per creare un nuovo database è per questo motivo che il file di movie.mdf è stato eliminato in un passaggio precedente.
Nella finestra della console di Gestione pacchetti immettere il comando "Add-migration Initial" per creare la migrazione iniziale. Il nome "Initial" è arbitrario e viene usato per denominare il file di migrazione creato.
Migrazioni Code First crea un altro file di classe nelCartella Migrations (con il nome {DateStamp}_Initial.cs ) e questa classe contiene codice che crea lo schema del database. Il nome file di migrazione è pre-corretto con un timestamp per facilitare l'ordinamento. Esaminare il file {DateStamp}_Initial.cs , che contiene le istruzioni per creare la tabella Movies per Movie DB. Quando si aggiorna il database nelle istruzioni seguenti, questo file {DateStamp}_Initial.cs verrà eseguito e creato lo schema del database. Il metodo Seed verrà quindi eseguito per popolare il database con i dati di test.
Nella console di Gestione pacchetti immettere il comando "update-database" per creare il database ed eseguire il metodo Seed.
Se viene visualizzato un errore che indica che esiste già una tabella e non è possibile crearla, è probabile che l'applicazione sia stata eseguita dopo l'eliminazione del database e prima dell'esecuzione update-database
di . In tal caso, eliminare nuovamente il file Movies.mdf e riprovare a eseguire il update-database
comando. Se si verifica ancora un errore, eliminare la cartella e il contenuto delle migrazioni, quindi iniziare con le istruzioni nella parte superiore di questa pagina, ovvero eliminare il file Movies.mdf , quindi procedere con Enable-Migrations.
Eseguire l'applicazione e passare all'URL /Movies . Vengono visualizzati i dati di inizializzazione.
Aggiunta di una proprietà Rating al modello Movie
Per iniziare, aggiungere una nuova Rating
proprietà alla classe esistente Movie
. Aprire il file Models\Movie.cs e aggiungere la Rating
proprietà come quella seguente:
public string Rating { get; set; }
La classe completa Movie
è ora simile al codice seguente:
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
public string Rating { get; set; }
}
Compilare l'applicazione usando il comando di menu Compila>filmato o premendo CTRL-MAIUSC-B.
Dopo aver aggiornato la Model
classe, è anche necessario aggiornare i modelli di visualizzazione \Views\Movies\Index.cshtml e \Views\Movies\Create.cshtml per visualizzare la nuova Rating
proprietà nella visualizzazione del browser.
Aprire il file\Views\Movies\Index.cshtml e aggiungere un'intestazione di <th>Rating</th>
colonna subito dopo la colonna Price . Aggiungere quindi una <td>
colonna alla fine del modello per eseguire il rendering del @item.Rating
valore. Di seguito è riportato l'aspetto del modello di visualizzazione Index.cshtml aggiornato:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Rating)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<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>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
Aprire quindi il file \Views\Movies\Create.cshtml e aggiungere il markup seguente alla fine del modulo. Questo esegue il rendering di una casella di testo in modo che sia possibile specificare una classificazione quando viene creato un nuovo film.
<div class="editor-label">
@Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
Il codice dell'applicazione è stato aggiornato per supportare la nuova Rating
proprietà.
Eseguire ora l'applicazione e passare all'URL /Movies . Quando si esegue questa operazione, tuttavia, verrà visualizzato uno degli errori seguenti:
Questo errore viene visualizzato perché la classe del modello aggiornata Movie
nell'applicazione è ora diversa dallo schema della Movie
tabella del 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 pratico quando si esegue lo sviluppo attivo in un database di test; consente di evolvere rapidamente lo schema del modello e del database insieme. Lo svantaggio, tuttavia, è che si perdono i dati esistenti nel database, quindi non si vuole usare questo approccio in un database di produzione. L'uso di un inizializzatore per eseguire automaticamente il seeding di un database con dati di test è spesso un modo produttivo per sviluppare un'applicazione. Per altre informazioni sugli inizializzatori di database di Entity Framework, vedere l'esercitazione ASP.NET MVC/Entity Framework di Tom Dykstra.
- 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 si userà Migrazioni Code First.
Aggiornare il metodo Seed in modo che fornisca un valore per la nuova colonna. Aprire Il file Migrations\Configuration.cs e aggiungere un campo Rating a ogni oggetto Movie.
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Rating = "G",
Price = 7.99M
},
Compilare la soluzione e quindi aprire la finestra della console di Gestione pacchetti e immettere il comando seguente:
add-migration AddRatingMig
Il add-migration
comando indica al framework di migrazione di esaminare il modello di film corrente con lo schema del database del film corrente e creare il codice necessario per eseguire la migrazione del database al nuovo modello. AddRatingMig è arbitrario e viene usato per denominare il file di migrazione. È utile usare un nome significativo per il passaggio di migrazione.
Al termine di questo comando, Visual Studio apre il file di classe che definisce la nuova DbMigration
classe derivata e nel Up
metodo è possibile visualizzare il codice che crea la nuova colonna.
public partial class AddRatingMig : DbMigration
{
public override void Up()
{
AddColumn("dbo.Movies", "Rating", c => c.String());
}
public override void Down()
{
DropColumn("dbo.Movies", "Rating");
}
}
Compilare la soluzione e quindi immettere il comando "update-database" nella finestra della console di Gestione pacchetti.
L'immagine seguente mostra l'output nella finestra della console di Gestione pacchetti (l'indicatore di data anteponendo AddRatingMig sarà diverso).
Eseguire di nuovo l'applicazione e passare all'URL /Movies. È possibile visualizzare il nuovo campo Valutazione.
Fare clic sul collegamento Crea nuovo per aggiungere un nuovo film. Si noti che è possibile aggiungere una valutazione.
Cliccare su Crea. Il nuovo film, incluso il rating, ora viene visualizzato nell'elenco dei film:
È anche necessario aggiungere il Rating
campo ai modelli di visualizzazione Edit, Details e SearchIndex.
È possibile immettere di nuovo il comando "update-database" nella finestra della console di Gestione pacchetti e non verranno apportate modifiche, perché lo schema corrisponde al modello.
In questa sezione è stato illustrato come modificare gli oggetti modello e mantenere il database sincronizzato con le modifiche. Si è anche appreso un modo per popolare un database appena creato con dati di esempio in modo da poter provare scenari. Si esaminerà ora come aggiungere logica di convalida più completa alle classi del modello e abilitare alcune regole business da applicare.