Teilen über


Teil 8: Hinzufügen eines neuen Felds zu einer ASP.NET Core MVC-App

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Von Rick Anderson

In diesem Abschnitt wird Entity Framework Migrationen verwendet, um Folgendes zu erreichen:

  • Dem Modell wird ein neues Feld hinzugefügt.
  • Das neue Feld wird in die Datenbank migriert.

Wenn Entity Framework (EF) verwendet wird, um automatisch eine Datenbank aus Modellklassen zu erstellen:

  • Wird der Datenbank eine Tabelle hinzugefügt, um das Schema der Datenbank nachzuverfolgen.
  • Es wird überprüft, ob die Datenbank mit den Modellklassen synchronisiert wird, aus denen sie generiert wurde. Wenn sie nicht synchron sind, löst EF eine Ausnahme aus. Dies erleichtert die Suche nach Problemen mit inkonsistenten Datenbanken bzw. inkonsistentem Code.

Hinzufügen einer Rating-Eigenschaft zum Movie-Modell

Fügen Sie eine Rating-Eigenschaft zu Models/Movie.cs hinzu:

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

Erstellen der App

Drücken Sie STRG+UMSCHALT+B

Da Sie der Movie-Klasse ein neues Feld hinzugefügt haben, müssen Sie die Eigenschaftenbindungsliste aktualisieren, damit diese neue Eigenschaft eingeschlossen wird. Aktualisieren Sie in MoviesController.cs das [Bind]-Attribut für die Aktionsmethoden Create und Edit so, dass die Rating-Eigenschaft eingeschlossen wird:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aktualisieren Sie die Ansichtsvorlagen, um die neue Rating-Eigenschaft in der Browseransicht anzuzeigen, zu erstellen und zu bearbeiten.

Bearbeiten Sie die Datei /Views/Movies/Index.cshtml, und fügen Sie ein Rating-Feld hinzu:

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

Aktualisieren Sie mit /Views/Movies/Create.cshtml einem Rating-Feld.

Sie können die vorherige „Formulargruppe“ kopieren und einfügen und IntelliSense die Felder aktualisieren lassen. IntelliSense nutzt Taghilfsprogramme.

Der Entwickler hat den Buchstaben R für den Attributwert von asp-for in das zweite Bezeichnungselement der Ansicht eingegeben. Es wird ein IntelliSense-Kontextmenü mit den verfügbaren Feldern angezeigt, einschließlich „Rating“ (Bewertung), das in der Liste automatisch hervorgehoben wird. Wenn der Entwickler auf das Feld klickt oder die EINGABETASTE auf der Tastatur drückt, wird der Wert auf „Rating“ festgelegt.

Fügen Sie die Rating -Eigenschaft den verbleibenden Create.cshtml, Delete.cshtml, Details.cshtmlund Edit.cshtml Ansichtsvorlagen hinzu.

Aktualisieren Sie die SeedData-Klasse so, dass sie einen Wert für die neue Spalte bereitstellt. Eine Beispieländerung wird nachstehend gezeigt, aber Sie sollten diese Änderung für jedes new Movie-Element vornehmen.

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

Die App funktioniert erst, nachdem die Datenbank mit dem neuen Feld aktualisiert wurde. Wird sie jetzt ausgeführt, wird die folgende SqlException ausgelöst:

SqlException: Invalid column name 'Rating'.

Dieser Fehler tritt auf, weil die aktualisierte Modellklasse „Movie“ sich vom Schema der Tabelle „Movie“ 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 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 in der Datenbank vorhandene Daten verloren gehen. Deshalb eignet sich dieser Ansatz nicht für eine Produktionsdatenbank! 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. Dies ist ein guter Ansatz für die frühe Entwicklung und wenn SQLite verwendet wird.

  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 Entity Framework-Migrationen, um das Datenbankschema zu aktualisieren.

In diesem Tutorial werden Entity Framework-Migrationen verwendet.

Wählen Sie im Menü Extras die Optionen NuGet-Paket-Manager > Paket-Manager-Konsole aus.

PMC-Menü

Geben Sie in der Paket-Manager-Konsole den folgenden Befehl ein:

Add-Migration Rating

Der Befehl Add-Migration weist das Migrationsframework an, das aktuelle Movie-Modell mit dem aktuellen Movie-Datenbankschema zu untersuchen und den notwendigen Code zu erstellen, um die Datenbank in das neue Modell zu migrieren.

Der Name „Rating“ ist beliebig und wird verwendet, um die Migrationsdatei zu benennen. Es ist hilfreich, einen aussagekräftigen Namen für die Migrationsdatei zu verwenden.

Werden alle Datensätze aus der Datenbank gelöscht, führt die initialize-Methode ein Seeding für die Datenbank aus und fügt das Feld Rating hinzu.

Geben Sie in der Paket-Manager-Konsole den folgenden Befehl ein:

Update-Database

Der Befehl "Update-Database" führt die Up-Methode in Migrationen aus, die nicht angewendet wurden.

Führen Sie die App aus, und überprüfen Sie, ob Sie Filme mit dem Feld Rating erstellen, bearbeiten und anzeigen können.

In diesem Abschnitt werden Entity Framework Code First-Migrationen für folgende Zwecke verwendet:

  • Dem Modell wird ein neues Feld hinzugefügt.
  • Das neue Feld wird in die Datenbank migriert.

Wird EF Code First verwendet, um eine Datenbank automatisch zu erstellen, geht Code First wie folgt vor:

  • Es fügt der Datenbank eine Tabelle hinzu, um das Schema der Datenbank nachzuverfolgen.
  • Es überprüft, ob die Datenbank mit den Modellklassen synchron ist, aus denen sie generiert wurde. Wenn sie nicht synchron sind, löst EF eine Ausnahme aus. Dies erleichtert die Suche nach Problemen mit inkonsistenten Datenbanken bzw. inkonsistentem Code.

Hinzufügen einer Rating-Eigenschaft zum Movie-Modell

Fügen Sie eine Rating-Eigenschaft zu Models/Movie.cs hinzu:

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

Erstellen der App

Drücken Sie STRG+UMSCHALT+B

Da Sie der Movie-Klasse ein neues Feld hinzugefügt haben, müssen Sie die Eigenschaftenbindungsliste aktualisieren, damit diese neue Eigenschaft eingeschlossen wird. Aktualisieren Sie in MoviesController.cs das [Bind]-Attribut für die Aktionsmethoden Create und Edit so, dass die Rating-Eigenschaft eingeschlossen wird:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aktualisieren Sie die Ansichtsvorlagen, um die neue Rating-Eigenschaft in der Browseransicht anzuzeigen, zu erstellen und zu bearbeiten.

Bearbeiten Sie die Datei /Views/Movies/Index.cshtml, und fügen Sie ein Rating-Feld hinzu:

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

Aktualisieren Sie mit /Views/Movies/Create.cshtml einem Rating-Feld.

Sie können die vorherige „Formulargruppe“ kopieren und einfügen und IntelliSense die Felder aktualisieren lassen. IntelliSense nutzt Taghilfsprogramme.

Der Entwickler hat den Buchstaben R für den Attributwert von asp-for in das zweite Bezeichnungselement der Ansicht eingegeben. Es wird ein IntelliSense-Kontextmenü mit den verfügbaren Feldern angezeigt, einschließlich „Rating“ (Bewertung), das in der Liste automatisch hervorgehoben wird. Wenn der Entwickler auf das Feld klickt oder die EINGABETASTE auf der Tastatur drückt, wird der Wert auf „Rating“ festgelegt.

Aktualisieren Sie die übrigen Vorlagen.

Aktualisieren Sie die SeedData-Klasse so, dass sie einen Wert für die neue Spalte bereitstellt. Eine Beispieländerung wird nachstehend gezeigt, aber Sie sollten diese Änderung für jedes new Movie-Element vornehmen.

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

Die App funktioniert erst, nachdem die Datenbank mit dem neuen Feld aktualisiert wurde. Wird sie jetzt ausgeführt, wird die folgende SqlException ausgelöst:

SqlException: Invalid column name 'Rating'.

Dieser Fehler tritt auf, weil die aktualisierte Modellklasse „Movie“ sich vom Schema der Tabelle „Movie“ 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 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 in der Datenbank vorhandene Daten verloren gehen. Deshalb eignet sich dieser Ansatz nicht für eine Produktionsdatenbank! 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. Dies ist ein guter Ansatz für die frühe Entwicklung und wenn SQLite verwendet wird.

  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 wird Code First-Migrationen verwendet.

Wählen Sie im Menü Tools nacheinander NuGet-Paket-Manager > Paket-Manager-Konsole aus.

PMC-Menü

Geben Sie in der PMC die folgenden Befehle ein:

Add-Migration Rating
Update-Database

Der Befehl Add-Migration weist das Migrationsframework an, das aktuelle Movie-Modell mit dem aktuellen Movie-Datenbankschema zu untersuchen und den notwendigen Code zu erstellen, um die Datenbank in das neue Modell zu migrieren.

Der Name „Rating“ ist beliebig und wird verwendet, um die Migrationsdatei zu benennen. Es ist hilfreich, einen aussagekräftigen Namen für die Migrationsdatei zu verwenden.

Werden alle Datensätze aus der Datenbank gelöscht, führt die initialize-Methode ein Seeding für die Datenbank aus und fügt das Feld Rating hinzu.

Führen Sie die App aus, und überprüfen Sie, ob Sie Filme mit dem Feld Rating erstellen, bearbeiten und anzeigen können.

In diesem Abschnitt werden Entity Framework Code First-Migrationen für folgende Zwecke verwendet:

  • Dem Modell wird ein neues Feld hinzugefügt.
  • Das neue Feld wird in die Datenbank migriert.

Wird EF Code First verwendet, um eine Datenbank automatisch zu erstellen, geht Code First wie folgt vor:

  • Es fügt der Datenbank eine Tabelle hinzu, um das Schema der Datenbank nachzuverfolgen.
  • Es überprüft, ob die Datenbank mit den Modellklassen synchron ist, aus denen sie generiert wurde. Wenn sie nicht synchron sind, löst EF eine Ausnahme aus. Dies erleichtert die Suche nach Problemen mit inkonsistenten Datenbanken bzw. inkonsistentem Code.

Hinzufügen einer Rating-Eigenschaft zum Movie-Modell

Fügen Sie eine Rating-Eigenschaft zu Models/Movie.cs hinzu:

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

Erstellen der App

Drücken Sie STRG+UMSCHALT+B

Da Sie der Movie-Klasse ein neues Feld hinzugefügt haben, müssen Sie die Eigenschaftenbindungsliste aktualisieren, damit diese neue Eigenschaft eingeschlossen wird. Aktualisieren Sie in MoviesController.cs das [Bind]-Attribut für die Aktionsmethoden Create und Edit so, dass die Rating-Eigenschaft eingeschlossen wird:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aktualisieren Sie die Ansichtsvorlagen, um die neue Rating-Eigenschaft in der Browseransicht anzuzeigen, zu erstellen und zu bearbeiten.

Bearbeiten Sie die Datei /Views/Movies/Index.cshtml, und fügen Sie ein Rating-Feld hinzu:

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

Aktualisieren Sie mit /Views/Movies/Create.cshtml einem Rating-Feld.

Sie können die vorherige „Formulargruppe“ kopieren und einfügen und IntelliSense die Felder aktualisieren lassen. IntelliSense nutzt Taghilfsprogramme.

Der Entwickler hat den Buchstaben R für den Attributwert von asp-for in das zweite Bezeichnungselement der Ansicht eingegeben. Es wird ein IntelliSense-Kontextmenü mit den verfügbaren Feldern angezeigt, einschließlich „Rating“ (Bewertung), das in der Liste automatisch hervorgehoben wird. Wenn der Entwickler auf das Feld klickt oder die EINGABETASTE auf der Tastatur drückt, wird der Wert auf „Rating“ festgelegt.

Aktualisieren Sie die übrigen Vorlagen.

Aktualisieren Sie die SeedData-Klasse so, dass sie einen Wert für die neue Spalte bereitstellt. Eine Beispieländerung wird nachstehend gezeigt, aber Sie sollten diese Änderung für jedes new Movie-Element vornehmen.

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

Die App funktioniert erst, nachdem die Datenbank mit dem neuen Feld aktualisiert wurde. Wird sie jetzt ausgeführt, wird die folgende SqlException ausgelöst:

SqlException: Invalid column name 'Rating'.

Dieser Fehler tritt auf, weil die aktualisierte Modellklasse „Movie“ sich vom Schema der Tabelle „Movie“ 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 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 in der Datenbank vorhandene Daten verloren gehen. Deshalb eignet sich dieser Ansatz nicht für eine Produktionsdatenbank! 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. Dies ist ein guter Ansatz für die frühe Entwicklung und wenn SQLite verwendet wird.

  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 wird Code First-Migrationen verwendet.

Wählen Sie im Menü Tools nacheinander NuGet-Paket-Manager > Paket-Manager-Konsole aus.

PMC-Menü

Geben Sie in der PMC die folgenden Befehle ein:

Add-Migration Rating
Update-Database

Der Befehl Add-Migration weist das Migrationsframework an, das aktuelle Movie-Modell mit dem aktuellen Movie-Datenbankschema zu untersuchen und den notwendigen Code zu erstellen, um die Datenbank in das neue Modell zu migrieren.

Der Name „Rating“ ist beliebig und wird verwendet, um die Migrationsdatei zu benennen. Es ist hilfreich, einen aussagekräftigen Namen für die Migrationsdatei zu verwenden.

Werden alle Datensätze aus der Datenbank gelöscht, führt die initialize-Methode ein Seeding für die Datenbank aus und fügt das Feld Rating hinzu.

Führen Sie die App aus, und überprüfen Sie, ob Sie Filme mit dem Feld Rating erstellen, bearbeiten und anzeigen können.

In diesem Abschnitt werden Entity Framework Code First-Migrationen für folgende Zwecke verwendet:

  • Dem Modell wird ein neues Feld hinzugefügt.
  • Das neue Feld wird in die Datenbank migriert.

Wird EF Code First verwendet, um eine Datenbank automatisch zu erstellen, geht Code First wie folgt vor:

  • Es fügt der Datenbank eine Tabelle hinzu, um das Schema der Datenbank nachzuverfolgen.
  • Es überprüft, ob die Datenbank mit den Modellklassen synchron ist, aus denen sie generiert wurde. Wenn sie nicht synchron sind, löst EF eine Ausnahme aus. Dies erleichtert die Suche nach Problemen mit inkonsistenten Datenbanken bzw. inkonsistentem Code.

Hinzufügen einer Rating-Eigenschaft zum Movie-Modell

Fügen Sie eine Rating-Eigenschaft zu Models/Movie.cs hinzu:

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

Erstellen der App

Strg+Umschalt+B

Da Sie der Movie-Klasse ein neues Feld hinzugefügt haben, müssen Sie die Eigenschaftenbindungsliste aktualisieren, damit diese neue Eigenschaft eingeschlossen wird. Aktualisieren Sie in MoviesController.cs das [Bind]-Attribut für die Aktionsmethoden Create und Edit so, dass die Rating-Eigenschaft eingeschlossen wird:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aktualisieren Sie die Ansichtsvorlagen, um die neue Rating-Eigenschaft in der Browseransicht anzuzeigen, zu erstellen und zu bearbeiten.

Bearbeiten Sie die Datei /Views/Movies/Index.cshtml, und fügen Sie ein Rating-Feld hinzu:

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

Aktualisieren Sie mit /Views/Movies/Create.cshtml einem Rating-Feld.

Sie können die vorherige „Formulargruppe“ kopieren und einfügen und IntelliSense die Felder aktualisieren lassen. IntelliSense nutzt Taghilfsprogramme.

Der Entwickler hat den Buchstaben R für den Attributwert von asp-for in das zweite Bezeichnungselement der Ansicht eingegeben. Es wird ein IntelliSense-Kontextmenü mit den verfügbaren Feldern angezeigt, einschließlich „Rating“ (Bewertung), das in der Liste automatisch hervorgehoben wird. Wenn der Entwickler auf das Feld klickt oder die EINGABETASTE auf der Tastatur drückt, wird der Wert auf „Rating“ festgelegt.

Aktualisieren Sie die übrigen Vorlagen.

Aktualisieren Sie die SeedData-Klasse so, dass sie einen Wert für die neue Spalte bereitstellt. Eine Beispieländerung wird nachstehend gezeigt, aber Sie sollten diese Änderung für jedes new Movie-Element vornehmen.

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

Die App funktioniert erst, nachdem die Datenbank mit dem neuen Feld aktualisiert wurde. Wird sie jetzt ausgeführt, wird die folgende SqlException ausgelöst:

SqlException: Invalid column name 'Rating'.

Dieser Fehler tritt auf, weil die aktualisierte Modellklasse „Movie“ sich vom Schema der Tabelle „Movie“ 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 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 in der Datenbank vorhandene Daten verloren gehen. Deshalb eignet sich dieser Ansatz nicht für eine Produktionsdatenbank! 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. Dies ist ein guter Ansatz für die frühe Entwicklung und wenn SQLite verwendet wird.

  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 wird Code First-Migrationen verwendet.

Wählen Sie im Menü Tools nacheinander NuGet-Paket-Manager > Paket-Manager-Konsole aus.

PMC-Menü

Geben Sie in der PMC die folgenden Befehle ein:

Add-Migration Rating
Update-Database

Der Befehl Add-Migration weist das Migrationsframework an, das aktuelle Movie-Modell mit dem aktuellen Movie-Datenbankschema zu untersuchen und den notwendigen Code zu erstellen, um die Datenbank in das neue Modell zu migrieren.

Der Name „Rating“ ist beliebig und wird verwendet, um die Migrationsdatei zu benennen. Es ist hilfreich, einen aussagekräftigen Namen für die Migrationsdatei zu verwenden.

Werden alle Datensätze aus der Datenbank gelöscht, führt die initialize-Methode ein Seeding für die Datenbank aus und fügt das Feld Rating hinzu.

Führen Sie die App aus, und überprüfen Sie, ob Sie Filme mit dem Feld Rating erstellen, bearbeiten und anzeigen können.

In diesem Abschnitt werden Entity Framework Code First-Migrationen für folgende Zwecke verwendet:

  • Dem Modell wird ein neues Feld hinzugefügt.
  • Das neue Feld wird in die Datenbank migriert.

Wird EF Code First verwendet, um eine Datenbank automatisch zu erstellen, geht Code First wie folgt vor:

  • Es fügt der Datenbank eine Tabelle hinzu, um das Schema der Datenbank nachzuverfolgen.
  • Es überprüft, ob die Datenbank mit den Modellklassen synchron ist, aus denen sie generiert wurde. Wenn sie nicht synchron sind, löst EF eine Ausnahme aus. Dies erleichtert die Suche nach Problemen mit inkonsistenten Datenbanken bzw. inkonsistentem Code.

Hinzufügen einer Rating-Eigenschaft zum Movie-Modell

Fügen Sie eine Rating-Eigenschaft zu Models/Movie.cs hinzu:

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

Erstellen der App

Strg+Umschalt+B

Da Sie der Movie-Klasse ein neues Feld hinzugefügt haben, müssen Sie die Eigenschaftenbindungsliste aktualisieren, damit diese neue Eigenschaft eingeschlossen wird. Aktualisieren Sie in MoviesController.cs das [Bind]-Attribut für die Aktionsmethoden Create und Edit so, dass die Rating-Eigenschaft eingeschlossen wird:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aktualisieren Sie die Ansichtsvorlagen, um die neue Rating-Eigenschaft in der Browseransicht anzuzeigen, zu erstellen und zu bearbeiten.

Bearbeiten Sie die Datei /Views/Movies/Index.cshtml, und fügen Sie ein Rating-Feld hinzu:

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

Aktualisieren Sie mit /Views/Movies/Create.cshtml einem Rating-Feld.

Sie können die vorherige „Formulargruppe“ kopieren und einfügen und IntelliSense die Felder aktualisieren lassen. IntelliSense nutzt Taghilfsprogramme.

Der Entwickler hat den Buchstaben R für den Attributwert von asp-for in das zweite Bezeichnungselement der Ansicht eingegeben. Es wird ein IntelliSense-Kontextmenü mit den verfügbaren Feldern angezeigt, einschließlich „Rating“ (Bewertung), das in der Liste automatisch hervorgehoben wird. Wenn der Entwickler auf das Feld klickt oder die EINGABETASTE auf der Tastatur drückt, wird der Wert auf „Rating“ festgelegt.

Aktualisieren Sie die übrigen Vorlagen.

Aktualisieren Sie die SeedData-Klasse so, dass sie einen Wert für die neue Spalte bereitstellt. Eine Beispieländerung wird nachstehend gezeigt, aber Sie sollten diese Änderung für jedes new Movie-Element vornehmen.

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

Die App funktioniert erst, nachdem die Datenbank mit dem neuen Feld aktualisiert wurde. Wird sie jetzt ausgeführt, wird die folgende SqlException ausgelöst:

SqlException: Invalid column name 'Rating'.

Dieser Fehler tritt auf, weil die aktualisierte Modellklasse „Movie“ sich vom Schema der Tabelle „Movie“ 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 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 in der Datenbank vorhandene Daten verloren gehen. Deshalb eignet sich dieser Ansatz nicht für eine Produktionsdatenbank! 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. Dies ist ein guter Ansatz für die frühe Entwicklung und wenn SQLite verwendet wird.

  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 wird Code First-Migrationen verwendet.

Wählen Sie im Menü Tools nacheinander NuGet-Paket-Manager > Paket-Manager-Konsole aus.

PMC-Menü

Geben Sie in der PMC die folgenden Befehle ein:

Add-Migration Rating
Update-Database

Der Befehl Add-Migration weist das Migrationsframework an, das aktuelle Movie-Modell mit dem aktuellen Movie-Datenbankschema zu untersuchen und den notwendigen Code zu erstellen, um die Datenbank in das neue Modell zu migrieren.

Der Name „Rating“ ist beliebig und wird verwendet, um die Migrationsdatei zu benennen. Es ist hilfreich, einen aussagekräftigen Namen für die Migrationsdatei zu verwenden.

Werden alle Datensätze aus der Datenbank gelöscht, führt die initialize-Methode ein Seeding für die Datenbank aus und fügt das Feld Rating hinzu.

Führen Sie die App aus, und überprüfen Sie, ob Sie Filme mit dem Feld Rating erstellen, bearbeiten und anzeigen können.

In diesem Abschnitt werden Entity Framework Code First-Migrationen für folgende Zwecke verwendet:

  • Dem Modell wird ein neues Feld hinzugefügt.
  • Das neue Feld wird in die Datenbank migriert.

Wird EF Code First verwendet, um eine Datenbank automatisch zu erstellen, geht Code First wie folgt vor:

  • Es fügt der Datenbank eine Tabelle hinzu, um das Schema der Datenbank nachzuverfolgen.
  • Es überprüft, ob die Datenbank mit den Modellklassen synchron ist, aus denen sie generiert wurde. Wenn sie nicht synchron sind, löst EF eine Ausnahme aus. Dies erleichtert die Suche nach Problemen mit inkonsistenten Datenbanken bzw. inkonsistentem Code.

Hinzufügen einer Rating-Eigenschaft zum Movie-Modell

Fügen Sie eine Rating-Eigenschaft zu Models/Movie.cs hinzu:

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

Erstellen der App

Strg+Umschalt+B

Da Sie der Movie-Klasse ein neues Feld hinzugefügt haben, müssen Sie die Eigenschaftenbindungsliste aktualisieren, damit diese neue Eigenschaft eingeschlossen wird. Aktualisieren Sie in MoviesController.cs das [Bind]-Attribut für die Aktionsmethoden Create und Edit so, dass die Rating-Eigenschaft eingeschlossen wird:

[Bind("Id,Title,ReleaseDate,Genre,Price,Rating")]

Aktualisieren Sie die Ansichtsvorlagen, um die neue Rating-Eigenschaft in der Browseransicht anzuzeigen, zu erstellen und zu bearbeiten.

Bearbeiten Sie die Datei /Views/Movies/Index.cshtml, und fügen Sie ein Rating-Feld hinzu:

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

Aktualisieren Sie mit /Views/Movies/Create.cshtml einem Rating-Feld.

Sie können die vorherige „Formulargruppe“ kopieren und einfügen und IntelliSense die Felder aktualisieren lassen. IntelliSense nutzt Taghilfsprogramme.

Der Entwickler hat den Buchstaben R für den Attributwert von asp-for in das zweite Bezeichnungselement der Ansicht eingegeben. Es wird ein IntelliSense-Kontextmenü mit den verfügbaren Feldern angezeigt, einschließlich „Rating“ (Bewertung), das in der Liste automatisch hervorgehoben wird. Wenn der Entwickler auf das Feld klickt oder die EINGABETASTE auf der Tastatur drückt, wird der Wert auf „Rating“ festgelegt.

Aktualisieren Sie die übrigen Vorlagen.

Aktualisieren Sie die SeedData-Klasse so, dass sie einen Wert für die neue Spalte bereitstellt. Eine Beispieländerung wird nachstehend gezeigt, aber Sie sollten diese Änderung für jedes new Movie-Element vornehmen.

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

Die App funktioniert erst, nachdem die Datenbank mit dem neuen Feld aktualisiert wurde. Wird sie jetzt ausgeführt, wird die folgende SqlException ausgelöst:

SqlException: Invalid column name 'Rating'.

Dieser Fehler tritt auf, weil die aktualisierte Modellklasse „Movie“ sich vom Schema der Tabelle „Movie“ 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 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 in der Datenbank vorhandene Daten verloren gehen. Deshalb eignet sich dieser Ansatz nicht für eine Produktionsdatenbank! 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. Dies ist ein guter Ansatz für die frühe Entwicklung und wenn SQLite verwendet wird.

  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 wird Code First-Migrationen verwendet.

Wählen Sie im Menü Tools nacheinander NuGet-Paket-Manager > Paket-Manager-Konsole aus.

PMC-Menü

Geben Sie in der PMC die folgenden Befehle ein:

Add-Migration Rating
Update-Database

Der Befehl Add-Migration weist das Migrationsframework an, das aktuelle Movie-Modell mit dem aktuellen Movie-Datenbankschema zu untersuchen und den notwendigen Code zu erstellen, um die Datenbank in das neue Modell zu migrieren.

Der Name „Rating“ ist beliebig und wird verwendet, um die Migrationsdatei zu benennen. Es ist hilfreich, einen aussagekräftigen Namen für die Migrationsdatei zu verwenden.

Werden alle Datensätze aus der Datenbank gelöscht, führt die initialize-Methode ein Seeding für die Datenbank aus und fügt das Feld Rating hinzu.

Führen Sie die App aus, und überprüfen Sie, ob Sie Filme mit dem Feld Rating erstellen, bearbeiten und anzeigen können.