Share via


Aggiunta di un nuovo campo al modello di filmato e alla tabella

di Rick Anderson

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 altre funzionalità.

In questa sezione si userà Migrazioni Code First di Entity Framework per eseguire la migrazione di alcune modifiche alle classi di 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 del fatto che lo schema del database sia sincronizzato con le classi di modello generate da. Se non sono sincronizzati, Entity Framework genera un errore. In questo modo è più semplice tenere traccia dei problemi in fase di sviluppo che potrebbero essere rilevati solo (da errori oscuri) 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 MovieDBContext e selezionare Elimina per eliminare il database dei film.

Screenshot che mostra la finestra Esplora server. L'eliminazione è selezionata nel menu Di scelta rapida Film D B.

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.

Screenshot che mostra la finestra Esplora soluzioni. L'eliminazione è selezionata nel menu di clic destro del punto film m d f.

Compilare l'applicazione e verificare che non siano presenti errori.

Dal menu Strumenti fare clic su Gestione pacchetti NuGet e quindi console di Gestione pacchetti.

Aggiungi pacchetto man

Nella finestra PM>Console di Gestione pacchetti immettere "Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext".

Screenshot che mostra la finestra Console di Gestione pacchetti. Viene immesso il comando Abilita migrazioni.

Il comando Enable-Migrations (illustrato sopra) crea un file Configuration.cs in una nuova cartella Migrations .

Screenshot che mostra la finestra Esplora soluzioni. La cartella Migrations e il file punto di configurazione c s sono cerchiati in rosso.

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 riga rossa sotto Movie e selezionare Risolvi e quindi usareMvcMovie.Models;

Screenshot che mostra Risoluzione selezionata nel menu Film con il pulsante destro del mouse.

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 li inserisce se non esistono ancora.

Premere CTRL-MAIUSC-B per compilare il progetto.La procedura seguente avrà esito negativo se non si compila a questo punto.

Il passaggio successivo consiste nel creare una DbMigration classe per la migrazione iniziale. Questa migrazione per creare un nuovo database, questo è il motivo per cui è stato eliminato il file movie.mdf in un passaggio precedente.

Nella finestra Console di Gestione pacchetti immettere il comando "Add-migration Initial" per creare la migrazione iniziale. Il nome "Initial" è arbitrario e viene usato per assegnare un nome al file di migrazione creato.

Screenshot che mostra la finestra Console di Gestione pacchetti. Il paragrafo che inizia con Il codice Designer per questo file di migrazione è evidenziato.

Migrazioni Code First crea un altro file di classe nella cartella Migrations (con il nome {DateStamp}_Initial.cs) e questa classe contiene codice che crea lo schema del database. Il nome del file di migrazione è predefinito con un timestamp per consentire l'ordinamento. Esaminare il file {DateStamp}_Initial.cs , contiene le istruzioni per creare la tabella Movies per il database Movie. Quando si aggiorna il database nelle istruzioni seguenti, questo file {DateStamp}_Initial.cs verrà eseguito e creato lo schema del database. Verrà quindi eseguito il metodo Seed 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 .

Screenshot che mostra la finestra Console di Gestione pacchetti. Il comando aggiorna database viene immesso.

Se viene visualizzato un errore che indica che esiste già una tabella e non è possibile creare, è probabile che l'applicazione sia stata eseguita dopo l'eliminazione del database e prima dell'esecuzione update-databasedi . In questo caso, eliminare di nuovo il file Movies.mdf e riprovare il update-database comando. Se si verifica ancora un errore, eliminare la cartella e il contenuto delle migrazioni, iniziare con le istruzioni nella parte superiore di questa pagina (ovvero eliminare il file Movies.mdf e quindi procedere a Enable-Migrations).

Eseguire l'applicazione e passare all'URL /Movies . Vengono visualizzati i dati di inizializzazione.

Screenshot che mostra la pagina Indice film M V C con un elenco di quattro film.

Aggiunta di una proprietà Rating al modello Movie

Iniziare aggiungendo una nuova Rating proprietà alla classe esistente Movie . Aprire il file Models\Movie.cs e aggiungere la Rating proprietà come questa:

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 ilcomando di menuCompila> film o premendo CTRL-MAIUSC-B.

Dopo aver aggiornato la Model classe, è necessario aggiornare anche 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 <th>Rating</th> di colonna appena dopo la colonna Price . Aggiungere quindi una <td> colonna alla fine del modello per eseguire il rendering del @item.Rating valore. Di seguito è riportato il 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. In questo modo viene eseguita 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>

È stato ora aggiornato il codice dell'applicazione 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:

Screenshot che mostra l'eccezione di operazione non valida non gestita dal codice utente.

Screenshot che mostra la finestra del browser con un errore che indica l'errore del server nell'applicazione.

Questo errore viene visualizzato perché la classe 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:

  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 pratico quando si esegue lo sviluppo attivo in un database di test; consente di evolvere rapidamente il modello e lo schema del database insieme. Il lato negativo, tuttavia, è che si perdono dati esistenti nel database, quindi non si vuole usare questo approccio in un database di produzione. L'uso di un inizializzatore per inizializzare automaticamente 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.
  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 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 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 assegnare un nome al 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 Console di Gestione pacchetti .

L'immagine seguente mostra l'output nella finestra Console di Gestione pacchetti (Il valore di addRatingMig pre-sospeso del segno di data sarà diverso).

Screenshot che mostra il comando di aggiornamento del database.

Eseguire nuovamente l'applicazione e passare all'URL /Movies. È possibile visualizzare il nuovo campo Valutazione.

Screenshot che mostra la pagina Indice film M V C con quattro film elencati.

Fare clic sul collegamento Crea nuovo per aggiungere un nuovo filmato. Si noti che è possibile aggiungere una classificazione.

7_CreateRioII

Fare clic su Crea. Il nuovo film, incluso il rating, ora viene visualizzato nell'elenco dei film:

7_ourNewMovie_SM

È anche necessario aggiungere il Rating campo ai modelli di visualizzazione Modifica, Dettagli e RicercaIndex.

È 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 gli scenari. Si esamini ora come aggiungere logica di convalida più completa alle classi di modello e abilitare alcune regole business da applicare.