Hinzufügen eines neuen Felds
von Rick Anderson
Hinweis
Eine aktualisierte Version dieses Lernprogramms ist hier mit der neuesten Version von Visual Studio verfügbar. Das neue Lernprogramm verwendet ASP.NET Core MVC, was viele Verbesserungen in diesem Lernprogramm bietet.
Dieses Tutorial vermittelt Informationen zu ASP.NET Core MVC mit Controllern und Ansichten. Razor Pages ist eine neue Alternative in ASP.NET Core, einem seitenbasierten Programmiermodell, das das Erstellen von Web-UI erleichtert und produktiver macht. Es empfiehlt sich, dass Sie sich das Tutorial der Razor Pages vor der MVC-Version ansehen. Das Tutorial zu Razor Pages:
- Ist einfacher zu befolgen.
- Behandelt mehr Features.
- Ist der bevorzugte Ansatz für die entwicklung neuer Apps.
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
Navigieren Sie 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. Wenn die Movies.mdf Datei nicht angezeigt wird, klicken Sie unten in der roten Gliederung auf das Symbol "Alle Dateien anzeigen".
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.
Geben Sie in das Paket-Manager Konsolenfenster an der PM>
Eingabeaufforderung
Enable-Migration -ContextTypeName MvcMovie.Models.MovieDBContext
Der Befehl "Enable-Migration" (siehe oben) erstellt eine Configuration.cs Datei in einem neuen Migrationsordner .
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
}
);
}
Zeigen Sie mit der Maus auf die rote Wellenlinie, Movie
und klicken Sie, und klicken Show Potential Fixes
Sie dann mit MvcMovie.Models;
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.
Die AddOrUpdate-Methode im folgenden Code führt einen Upsert-Vorgang aus:
context.Movies.AddOrUpdate(i => i.Title,
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Rating = "PG",
Price = 7.99M
}
Da die Seed-Methode mit jeder Migration ausgeführt wird, können Sie nicht nur Daten einfügen, da die Zeilen, die Sie hinzufügen möchten, bereits nach der ersten Migration vorhanden sind, die die Datenbank erstellt. Der Vorgang "upsert" verhindert Fehler, die auftreten würden, wenn Sie versuchen, eine Zeile einzufügen, die bereits vorhanden ist, aber alle Änderungen an Daten außer Kraft setzt, die Sie möglicherweise beim Testen der Anwendung vorgenommen haben. Bei Testdaten in einigen Tabellen möchten Sie dies möglicherweise nicht: in einigen Fällen, wenn Sie Daten ändern, während Sie testen, dass Ihre Änderungen nach Datenbankaktualisierungen verbleiben sollen. In diesem Fall möchten Sie einen Vorgang zum bedingten Einfügen ausführen: Fügen Sie eine Zeile nur ein, wenn sie noch nicht vorhanden ist.
Der erste Parameter, der an die AddOrUpdate-Methode übergeben wird, gibt die Eigenschaft an, die verwendet werden soll, um zu überprüfen, ob bereits eine Zeile vorhanden ist. Für die von Ihnen bereitgestellten Testfilmdaten kann die Title
Eigenschaft zu diesem Zweck verwendet werden, da jeder Titel in der Liste eindeutig ist:
context.Movies.AddOrUpdate(i => i.Title,
Dieser Code geht davon aus, dass Titel eindeutig sind. Wenn Sie manuell einen doppelten Titel hinzufügen, erhalten Sie beim nächsten Ausführen einer Migration die folgende Ausnahme.
Sequenz enthält mehr als ein Element
Weitere Informationen zur AddOrUpdate-Methode finden Sie unter EF 4.3 AddOrUpdate-Methode..
Drücken Sie STRG-UMSCHALT-B, um das Projekt zu erstellen.(Die folgenden Schritte schlagen fehl, wenn Sie zu diesem Zeitpunkt nicht erstellen.)
Der nächste Schritt besteht darin, eine DbMigration
Klasse für die erste Migration zu erstellen. Diese Migration erstellt eine neue Datenbank, 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.
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 Movies
Tabelle 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.
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-database
haben. 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. Wenn immer noch ein Fehler auftritt, öffnen Sie SQL Server Objekt-Explorer, und entfernen Sie die Datenbank aus der Liste. Wenn ein Fehler angezeigt wird, der angibt, dass die Datei .mdf als Datenbank nicht angefügt werden kann, entfernen Sie die Eigenschaft "Initial Catalog" als Teil der Verbindungszeichenfolge in der Datei "web.config".
Führen Sie die Anwendung aus, und navigieren Sie zur URL "/Movies ". Die Startdaten werden angezeigt.
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; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
public string Rating { get; set; }
}
Erstellen Sie die Anwendung (STRG+UMSCHALT+B).
Da Sie der Movie
Klasse ein neues Feld hinzugefügt haben, müssen Sie auch die Bindungs-Zulassungsliste aktualisieren, damit diese neue Eigenschaft einbezogen wird. Aktualisieren Sie das bind
Attribut für Create
und Edit
Aktionsmethoden, um die Rating
Eigenschaft einzuschließen:
[Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")]
Sie müssen auch die Ansichtsvorlagen aktualisieren, um die neue Rating
-Eigenschaft in der Browseransicht anzuzeigen, zu erstellen und zu bearbeiten.
Ö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")
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
{
<p>
Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
</p>
<table class="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 Rating
Feld mit dem folgenden hervorgehobenen Markup hinzu. Dadurch wird ein Textfeld gerendert, sodass Sie beim Erstellen eines neuen Films eine Bewertung angeben können.
<div class="form-group">
@Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Rating, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Rating, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Rating, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Sie haben nun den Anwendungscode aktualisiert, um die neue Rating
Eigenschaft zu unterstützen.
Führen Sie die Anwendung aus, und navigieren Sie zur URL "/Movies ". In diesem Fall sehen Sie jedoch einen der folgenden Fehler:
Das Modell, das den Kontext "MovieDBContext" unterstützt, wurde seit der Erstellung der Datenbank geändert. Erwägen Sie die Verwendung von Code First-Migrationen zum Aktualisieren der Datenbank (https://go.microsoft.com/fwlink/?LinkId=238269).
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:
- Lassen Sie die Datenbank von Entity Framework automatisch löschen und basierend auf dem neuen Modellklassenschema neu erstellen. Dieser Ansatz ist früh im Entwicklungszyklus sehr praktisch, wenn die aktive Entwicklung in einer Testdatenbank erfolgt. Er ermöglicht Ihnen, das Modell und das Datenbankschema schnell weiterzuentwickeln. Der Nachteil ist jedoch, dass Sie vorhandene Daten in der Datenbank verlieren – daher möchten Sie diesen Ansatz nicht für eine Produktionsdatenbank verwenden! Das Verwenden eines Initialisierers zum automatischen Ausführen eines Seedings für eine Datenbank mit Testdaten ist häufig eine produktive Möglichkeit zum Entwickeln einer Anwendung. Weitere Informationen zu Entity Framework-Datenbankinitialisierern finden Sie im Lernprogramm ASP.NET MVC/Entity Framework.
- Ä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.
- 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 = "PG",
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 Rating
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. Die Namensbewertung 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 update-database
Befehl im Paket-Manager Konsolenfenster ein.
Die folgende Abbildung zeigt die Ausgabe im Paket-Manager Konsolenfenster (Der Datumsstempel vor der Bewertung ist unterschiedlich.)
Führen Sie die Anwendung erneut aus, und navigieren Sie zur URL "/Movies". Das neue Bewertungsfeld wird angezeigt.
Klicken Sie auf den Link "Neu erstellen", um einen neuen Film hinzuzufügen. Beachten Sie, dass Sie eine Bewertung hinzufügen können.
Klicken Sie auf Erstellen. Der neue Film, einschließlich der Bewertung, wird jetzt im Filmeintrag angezeigt:
Nachdem das Projekt Migrationen verwendet, müssen Sie die Datenbank nicht ablegen, wenn Sie ein neues Feld hinzufügen oder das Schema auf andere Weise aktualisieren. Im nächsten Abschnitt nehmen wir weitere Schemaänderungen vor und verwenden Migrationen, um die Datenbank zu aktualisieren.
Sie sollten das Rating
Feld auch den Ansichtsvorlagen "Bearbeiten", "Details" und "Löschen" hinzufügen.
Sie könnten den Befehl "update-database" im fenster Paket-Manager Konsole erneut eingeben und kein Migrationscode ausgeführt werden, da das Schema mit dem Modell übereinstimmt. Wenn Sie jedoch "update-database" ausführen, wird die Seed
Methode erneut ausgeführt, und wenn Sie einen der Seed-Daten geändert haben, gehen die Änderungen verloren, da die Seed
Methode Daten aufwärtst. Weitere Informationen zur Seed
Methode finden Sie im beliebten ASP.NET MVC/Entity Framework-Lernprogramm von Tom Dykstra.
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. Dies war nur eine kurze Einführung in Code First, siehe Erstellen eines Entity Framework-Datenmodells für eine ASP.NET MVC-Anwendung für ein vollständiges Lernprogramm zum Thema. Als Nächstes sehen wir uns an, wie Sie den Modellklassen eine umfangreichere Validierungslogik hinzufügen und einige Geschäftsregeln erzwingen können.