Hinzufügen eines neuen Felds zum Modell und zur Tabelle eines Films

von Rick Anderson

Hinweis

Hier ist eine aktualisierte Version dieses Lernprogramms verfügbar, die ASP.NET MVC 5 und Visual Studio 2013 verwendet. Es ist sicherer, viel einfacher zu folgen und zeigt weitere Features.

In diesem Abschnitt verwenden Sie Entity Framework Code First-Migrationen, um einige Änderungen an den Modellklassen zu migrieren, sodass die Änderung auf die Datenbank angewendet wird.

Wenn Sie entity Framework Code First zum automatischen Erstellen einer Datenbank verwenden, wie sie in diesem Lernprogramm bereits erwähnt haben, fügt Code First der Datenbank eine Tabelle hinzu, um nachzuverfolgen, ob das Schema der Datenbank mit den Modellklassen synchronisiert ist, aus denen sie generiert wurde. Wenn sie nicht synchronisiert sind, löst Entity Framework einen Fehler aus. Dies erleichtert das Auffinden von Problemen zur Entwicklungszeit, die sonst nur zur Laufzeit (durch verdeckte Fehler) gefunden werden können.

Einrichten von Code First-Migrationen für Modelländerungen

Wenn Sie Visual Studio 2012 verwenden, doppelklicken Sie auf die Movies.mdf Datei aus Projektmappen-Explorer, um das Datenbanktool zu öffnen. Visual Studio Express für Web zeigt den Datenbank-Explorer an. Visual Studio 2012 zeigt den Server-Explorer an. Wenn Sie Visual Studio 2010 verwenden, verwenden Sie SQL Server Objekt-Explorer.

Klicken Sie im Datenbanktool (Datenbank-Explorer, Server-Explorer oder SQL Server-Objekt-Explorer) mit der rechten Maustaste, MovieDBContext und wählen Sie "Löschen" aus, um die Filmdatenbank abzulegen.

Screenshot des Fensters

Navigieren Sie zurück zu Projektmappen-Explorer. Klicken Sie mit der rechten Maustaste auf die Movies.mdf Datei, und wählen Sie " Löschen " aus, um die Filmdatenbank zu entfernen.

Screenshot des fensters

Erstellen Sie die Anwendung, um sicherzustellen, dass keine Fehler vorliegen.

Klicken Sie im Menü Extras auf NuGet-Paket-Manager und dann auf Paket-Manager-Konsole.

Pack Man hinzufügen

Geben Sie im Paket-Manager Konsolenfenster an der PM> Eingabeaufforderung "Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext" ein.

Screenshot des Paket-Manager Konsolenfensters. Der Befehl 'Migrationen aktivieren' wird eingegeben.

Der Befehl "Enable-Migration" (siehe oben) erstellt eine Configuration.cs Datei in einem neuen Migrationsordner .

Screenshot des fensters

Visual Studio öffnet die Configuration.cs Datei. Ersetzen Sie die Seed Methode in der datei Configuration.cs durch den folgenden Code:

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

Klicken Sie mit der rechten Maustaste auf die rote Wellenlinie, Movie und wählen Sie dann "Auflösen" und dann "MvcMovie.Models" aus.

Screenshot, der zeigt, dass

Dadurch wird die folgende using-Anweisung hinzugefügt:

using MvcMovie.Models;

Hinweis

Code First-Migrationen ruft die Seed Methode nach jeder Migration auf (d. h. aktualisierungsdatenbank in der Paket-Manager Konsole), und diese Methode aktualisiert Zeilen, die bereits eingefügt wurden, oder fügt sie ein, wenn sie noch nicht vorhanden sind.

Drücken Sie STRG-UMSCHALT-B, um das Projekt zu erstellen.(Die folgenden Schritte schlagen fehl, wenn Ihr Build an diesem Punkt nicht erstellt wird.)

Der nächste Schritt besteht darin, eine DbMigration Klasse für die erste Migration zu erstellen. Mit dieser Migration wird eine neue Datenbank erstellt, weshalb Sie die movie.mdf Datei in einem vorherigen Schritt gelöscht haben.

Geben Sie im Paket-Manager Konsolenfenster den Befehl "Add-Migration Initial" ein, um die erste Migration zu erstellen. Der Name "Initial" ist willkürlich und wird verwendet, um die erstellte Migrationsdatei zu benennen.

Screenshot des Paket-Manager Konsolenfensters. Der Absatz, der mit dem Designercode für diese Migrationsdatei beginnt, ist hervorgehoben.

Code First-Migrationen erstellt eine weitere Klassendatei in der Migrationsordner (mit dem Namen {DateStamp}_Initial.cs) und diese Klasse enthält Code, der das Datenbankschema erstellt. Dem Dateinamen der Migration ist ein Zeitstempel vorangestellt, um die Sortierung zu erleichtern. Überprüfen Sie die Datei "{DateStamp}_Initial.cs ", sie enthält die Anweisungen zum Erstellen der Tabelle "Filme" für die Movie DB. Wenn Sie die Datenbank in den nachstehenden Anweisungen aktualisieren, wird diese {DateStamp}_Initial.cs Datei ausgeführt und das DB-Schema erstellt. Anschließend wird die Seed-Methode ausgeführt, um die DB mit Testdaten aufzufüllen.

Geben Sie in der Paket-Manager-Konsole den Befehl "update-database" ein, um die Datenbank zu erstellen und die Seed-Methode auszuführen.

Screenshot des Paket-Manager Konsolenfensters. Der Befehl 'Datenbank aktualisieren' wird eingegeben.

Wenn ein Fehler angezeigt wird, der angibt, dass bereits eine Tabelle vorhanden ist und nicht erstellt werden kann, liegt es wahrscheinlich daran, dass Sie die Anwendung nach dem Löschen der Datenbank und vor der Ausführung ausgeführt update-databasehaben. Löschen Sie in diesem Fall die Movies.mdf Datei erneut, und wiederholen Sie den update-database Befehl. Wenn immer noch ein Fehler angezeigt wird, löschen Sie den Migrationsordner und die Inhalte, und beginnen Sie dann mit den Anweisungen oben auf dieser Seite (d. a. löschen Sie die Movies.mdf Datei, und fahren Sie dann mit "Enable-Migration" fort.

Führen Sie die Anwendung aus, und navigieren Sie zur URL "/Movies ". Die Startdaten werden angezeigt.

Screenshot der Seite

Hinzufügen einer Rating-Eigenschaft zum Movie-Modell

Beginnen Sie, indem Sie der vorhandenen Movie Klasse eine neue Rating Eigenschaft hinzufügen. Öffnen Sie die Datei Models\Movie.cs , und fügen Sie die Rating Eigenschaft wie folgt hinzu:

public string Rating { get; set; }

Die vollständige Movie Klasse sieht nun wie der folgende Code aus:

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

Erstellen Sie die Anwendung mithilfe des >Menübefehls "Build Movie" oder durch Drücken von STRG-UMSCHALT-B.

Nachdem Sie die Model Klasse aktualisiert haben, müssen Sie auch die Vorlagen \Views\Movies\Index.cshtml und \Views\Movies\Create.cshtml aktualisieren, um die neue Rating Eigenschaft in der Browseransicht anzuzeigen.

Öffnen Sie die Datei \Views\Movies\Index.cshtml, und fügen Sie direkt hinter der Spalte "Preis" eine <th>Rating</th> Spaltenüberschrift hinzu. Fügen Sie dann eine <td> Spalte am Ende der Vorlage hinzu, um den @item.Rating Wert zu rendern. Nachfolgend sehen Sie, wie die aktualisierte Index.cshtml-Ansichtsvorlage aussieht:

@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>

Öffnen Sie als Nächstes die Datei \Views\Movies\Create.cshtml , und fügen Sie das folgende Markup am Ende des Formulars hinzu. Dadurch wird ein Textfeld gerendert, sodass Sie beim Erstellen eines neuen Films eine Bewertung angeben können.

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

Sie haben nun den Anwendungscode aktualisiert, um die neue Rating Eigenschaft zu unterstützen.

Führen Sie nun die Anwendung aus, und navigieren Sie zur URL "/Movies ". In diesem Fall sehen Sie jedoch einen der folgenden Fehler:

Screenshot, der den Fehler

Screenshot des Browserfensters mit einem Fehler, der den Serverfehler in Der Anwendung angibt.

Dieser Fehler wird angezeigt, da sich die aktualisierte Movie Modellklasse in der Anwendung jetzt von dem Schema der Movie Tabelle der vorhandenen Datenbank unterscheidet. (Die Datenbanktabelle enthält nicht die Spalte Rating.)

Es gibt mehrere Vorgehensweisen zum Beheben des Fehlers:

  1. Lassen Sie die Datenbank von Entity Framework automatisch löschen und basierend auf dem neuen Modellklassenschema neu erstellen. Dieser Ansatz ist sehr praktisch bei der aktiven Entwicklung in einer Testdatenbank; sie ermöglicht es Ihnen, das Modell und das Datenbankschema schnell zusammen zu entwickeln. Der Nachteil ist jedoch, dass Sie vorhandene Daten in der Datenbank verlieren – daher möchten Sie diesen Ansatz nicht für eine Produktionsdatenbank verwenden! Die Verwendung eines Initialisierungsprogramms zum automatischen Seeden einer Datenbank mit Testdaten ist häufig eine produktive Möglichkeit zum Entwickeln einer Anwendung. Weitere Informationen zu Entity Framework-Datenbankinitialisierern finden Sie im Lernprogramm zum ASP.NET MVC/Entity Framework von Tom Dykstra.
  2. Ändern Sie das Schema der vorhandenen Datenbank explizit so, dass es mit den Modellklassen übereinstimmt. Der Vorteil dieses Ansatzes ist, dass Sie Ihre Daten behalten. Sie können diese Änderung entweder manuell oder durch Erstellen eines Änderungsskripts für die Datenbank vornehmen.
  3. Verwenden Sie Code First-Migrationen, um das Datenbankschema zu aktualisieren.

Für dieses Tutorial verwenden wir Code First-Migrationen.

Aktualisieren Sie die Seed-Methode so, dass sie einen Wert für die neue Spalte bereitstellt. Öffnen Sie migration\Configuration.cs Datei, und fügen Sie jedem Movie-Objekt ein Bewertungsfeld hinzu.

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

Erstellen Sie die Lösung, und öffnen Sie dann das Paket-Manager Konsolenfenster, und geben Sie den folgenden Befehl ein:

add-migration AddRatingMig

Der add-migration Befehl weist das Migrationsframework an, das aktuelle Filmmodell mit dem aktuellen Film DB-Schema zu untersuchen und den erforderlichen Code zum Migrieren der DB zum neuen Modell zu erstellen. AddRatingMig ist willkürlich und wird verwendet, um die Migrationsdatei zu benennen. Es ist hilfreich, einen aussagekräftigen Namen für den Migrationsschritt zu verwenden.

Nach Abschluss dieses Befehls öffnet Visual Studio die Klassendatei, die die neue DbMigration abgeleitete Klasse definiert, und in der Up Methode wird der Code angezeigt, der die neue Spalte erstellt.

public partial class AddRatingMig : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Movies", "Rating", c => c.String());
    }
    
    public override void Down()
    {
        DropColumn("dbo.Movies", "Rating");
    }
}

Erstellen Sie die Lösung, und geben Sie dann den Befehl "update-database" im Paket-Manager Konsolenfenster ein.

Die folgende Abbildung zeigt die Ausgabe im Paket-Manager Konsolenfenster (Der Datumsstempel vor dem Ausstehen von AddRatingMig ist unterschiedlich.)

Screenshot des Befehls

Führen Sie die Anwendung erneut aus, und navigieren Sie zur URL "/Movies". Das neue Bewertungsfeld wird angezeigt.

Screenshot der Seite

Klicken Sie auf den Link "Neu erstellen", um einen neuen Film hinzuzufügen. Beachten Sie, dass Sie eine Bewertung hinzufügen können.

7_CreateRioII

Klicken Sie auf Erstellen. Der neue Film, einschließlich der Bewertung, wird jetzt im Filmeintrag angezeigt:

7_ourNewMovie_SM

Sie sollten das Rating Feld auch den Ansichtsvorlagen "Bearbeiten", "Details" und "SearchIndex" hinzufügen.

Sie könnten den Befehl "update-database" im fenster Paket-Manager Konsole erneut eingeben und keine Änderungen vornehmen, da das Schema mit dem Modell übereinstimmt.

In diesem Abschnitt haben Sie gesehen, wie Sie Modellobjekte ändern und die Datenbank mit den Änderungen synchronisieren können. Außerdem haben Sie gelernt, wie Sie eine neu erstellte Datenbank mit Beispieldaten auffüllen können, damit Sie Szenarien ausprobieren können. Als Nächstes sehen wir uns an, wie Sie den Modellklassen eine umfangreichere Validierungslogik hinzufügen und einige Geschäftsregeln erzwingen können.