Ajouter un nouveau champ à une page Razor dans ASP.NET CoreAdd a new field to a Razor Page in ASP.NET Core

De Rick AndersonBy Rick Anderson

Dans cette section, Migrations Entity Framework Code First est utilisé pour :In this section Entity Framework Code First Migrations is used to:

  • Ajouter un nouveau champ au modèle.Add a new field to the model.
  • Migrer la nouvelle modification du schéma des champs vers la base de données.Migrate the new field schema change to the database.

Quand vous utilisez EF Code First pour créer automatiquement une base de données, Code First :When using EF Code First to automatically create a database, Code First:

  • Ajoute une table __EFMigrationsHistory à la base de données pour déterminer si le schéma de la base de données est synchronisé avec les classes de modèle à partir desquelles il a été généré.Adds an __EFMigrationsHistory table to the database to track whether the schema of the database is in sync with the model classes it was generated from.
  • Si les classes de modèle ne sont pas synchronisées avec la base de données, EF lève une exception.If the model classes aren't in sync with the DB, EF throws an exception.

La vérification automatique de la synchronisation du schéma et du modèle facilite la détection des problèmes d’incohérence et de code de base de données.Automatic verification of schema/model in sync makes it easier to find inconsistent database/code issues.

Ajout d’une propriété Rating au modèle MovieAdding a Rating Property to the Movie Model

Ouvrez le fichier Models/Movie.cs et ajoutez une propriété Rating :Open the Models/Movie.cs file and add a Rating property:

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

Générez l'application.Build the app.

Modifiez Pages/Movies/Index.cshtmlet ajoutez un champ Rating :Edit Pages/Movies/Index.cshtml, and add a Rating field:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

<table class="table">

    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movie)
        {
            <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-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                    <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                    <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Mettez à jour les pages suivantes :Update the following pages:

  • Ajoutez le champ Rating aux pages Delete et Details.Add the Rating field to the Delete and Details pages.
  • Mettez à jour Create.cshtml avec un champ Rating.Update Create.cshtml with a Rating field.
  • Ajoutez le champ Rating à la Page Edit.Add the Rating field to the Edit Page.

L’application ne fonctionne pas tant que la base de données n’est pas mise à jour pour inclure le nouveau champ.The app won't work until the DB is updated to include the new field. L’exécution de l’application sans mettre à jour la base de données lève une SqlException:Running the app without updating the database throws a SqlException:

SqlException: Invalid column name 'Rating'.

L’exception SqlException est provoquée par la classe de modèle Movie mise à jour qui est différente de celle du schéma de la table Movie de la base de données.The SqlException exception is caused by the updated Movie model class being different than the schema of the Movie table of the database. (Il n’existe pas de colonne Rating dans la table de base de données.)(There's no Rating column in the database table.)

Plusieurs approches sont possibles pour résoudre l’erreur :There are a few approaches to resolving the error:

  1. Laisser Entity Framework supprimer et recréer automatiquement la base de données avec le nouveau schéma de classes du modèle.Have the Entity Framework automatically drop and re-create the database using the new model class schema. Cette approche est très utile au début du cycle de développement. Elle permet de faire évoluer rapidement le modèle et le schéma de base de données ensemble.This approach is convenient early in the development cycle; it allows you to quickly evolve the model and database schema together. L’inconvénient est que vous perdez les données existantes dans la base de données.The downside is that you lose existing data in the database. N’utilisez pas cette approche sur une base de données de production !Don't use this approach on a production database! La suppression de la base de données lors des changements de schéma et l’utilisation d’un initialiseur pour amorcer automatiquement la base de données avec des données de test est souvent un moyen efficace pour développer une application.Dropping the DB on schema changes and using an initializer to automatically seed the database with test data is often a productive way to develop an app.

  2. Modifiez explicitement le schéma de la base de données existante pour le faire correspondre aux classes du modèle.Explicitly modify the schema of the existing database so that it matches the model classes. L’avantage de cette approche est que vous conservez vos données.The advantage of this approach is that you keep your data. Vous pouvez apporter cette modification manuellement ou en créant un script de modification de la base de données.You can make this change either manually or by creating a database change script.

  3. Utilisez Migrations Code First pour mettre à jour le schéma de base de données.Use Code First Migrations to update the database schema.

Pour ce didacticiel, nous allons utiliser les migrations Code First.For this tutorial, use Code First Migrations.

Mettez à jour la classe SeedData pour qu’elle fournisse une valeur pour la nouvelle colonne.Update the SeedData class so that it provides a value for the new column. Vous pouvez voir un exemple de modification ci-dessous, mais elle doit être appliquée à chaque bloc new Movie.A sample change is shown below, but you'll want to make this change for each new Movie block.

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

Consultez le fichier SeedData.cs complet.See the completed SeedData.cs file.

Générez la solution.Build the solution.

Ajouter une migration pour le champ d’évaluationAdd a migration for the rating field

Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du Gestionnaire de package.From the Tools menu, select NuGet Package Manager > Package Manager Console. Dans la console du Gestionnaire de package, entrez les commandes suivantes :In the PMC, enter the following commands:

Add-Migration Rating
Update-Database

La commande Add-Migration indique au framework qu’il doit :The Add-Migration command tells the framework to:

  • Comparer le modèle Movie au schéma de base de données MovieCompare the Movie model with the Movie DB schema.
  • Créer du code pour migrer le schéma de base de données vers le nouveau modèleCreate code to migrate the DB schema to the new model.

Le nom « Rating » est arbitraire et est utilisé pour nommer le fichier de migration.The name "Rating" is arbitrary and is used to name the migration file. Il est utile d’utiliser un nom explicite pour le fichier de migration.It's helpful to use a meaningful name for the migration file.

La commande Update-Database indique à l’infrastructure d’appliquer les modifications de schéma à la base de données et de conserver les données existantes.The Update-Database command tells the framework to apply the schema changes to the database and to preserve existing data.

Si vous supprimez tous les enregistrements de la base de données, l’initialiseur amorce la base de données et inclut le champ Rating.If you delete all the records in the DB, the initializer will seed the DB and include the Rating field. Pour ce faire, utilisez les liens de suppression disponibles dans le navigateur ou à partir de Sql Server Object Explorer.You can do this with the delete links in the browser or from Sql Server Object Explorer (SSOX).

Une autre option consiste à supprimer la base de données et à utiliser des migrations pour recréer la base de données.Another option is to delete the database and use migrations to re-create the database. Pour supprimer la base de données dans SSOX :To delete the database in SSOX:

  • Sélectionnez la base de données dans SSOX.Select the database in SSOX.

  • Cliquez avec le bouton droit sur la base de données, puis sélectionnez Supprimer.Right click on the database, and select Delete.

  • Cochez Fermer les connexions existantes.Check Close existing connections.

  • Sélectionnez OK.Select OK.

  • Dans la console du gestionnaire de package, mettez à jour la base de données :In the PMC, update the database:

    Update-Database
    

Exécutez l’application et vérifiez que vous pouvez créer/modifier/afficher des films avec un champ Rating.Run the app and verify you can create/edit/display movies with a Rating field. Si la base de données n’est pas amorcée, définissez un point d’arrêt dans la méthode SeedData.Initialize.If the database isn't seeded, set a break point in the SeedData.Initialize method.

Ressources supplémentairesAdditional resources

Dans cette section, Migrations Entity Framework Code First est utilisé pour :In this section Entity Framework Code First Migrations is used to:

  • Ajouter un nouveau champ au modèle.Add a new field to the model.
  • Migrer la nouvelle modification du schéma des champs vers la base de données.Migrate the new field schema change to the database.

Quand vous utilisez EF Code First pour créer automatiquement une base de données, Code First :When using EF Code First to automatically create a database, Code First:

  • Ajoute une table à la base de données pour déterminer si le schéma de la base de données est synchronisé avec les classes de modèle à partir desquelles il a été généré.Adds a table to the database to track whether the schema of the database is in sync with the model classes it was generated from.
  • Si les classes de modèle ne sont pas synchronisées avec la base de données, EF lève une exception.If the model classes aren't in sync with the DB, EF throws an exception.

La vérification automatique de la synchronisation du schéma et du modèle facilite la détection des problèmes d’incohérence et de code de base de données.Automatic verification of schema/model in sync makes it easier to find inconsistent database/code issues.

Ajout d’une propriété Rating au modèle MovieAdding a Rating Property to the Movie Model

Ouvrez le fichier Models/Movie.cs et ajoutez une propriété Rating :Open the Models/Movie.cs file and add a Rating property:

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

Générez l'application.Build the app.

Modifiez Pages/Movies/Index.cshtmlet ajoutez un champ Rating :Edit Pages/Movies/Index.cshtml, and add a Rating field:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

<table class="table">

    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Rating)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movie)
        {
        <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-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
        }
    </tbody>
</table>

Mettez à jour les pages suivantes :Update the following pages:

  • Ajoutez le champ Rating aux pages Delete et Details.Add the Rating field to the Delete and Details pages.
  • Mettez à jour Create.cshtml avec un champ Rating.Update Create.cshtml with a Rating field.
  • Ajoutez le champ Rating à la Page Edit.Add the Rating field to the Edit Page.

L’application ne fonctionne pas tant que la base de données n’est pas mise à jour pour inclure le nouveau champ.The app won't work until the DB is updated to include the new field. Si vous l’exécutez à présent, l’application lève une SqlException :If run now, the app throws a SqlException:

SqlException: Invalid column name 'Rating'.

Cette erreur est due au fait que la classe du modèle Movie mise à jour est différente du schéma de la table Movie de la base de données.This error is caused by the updated Movie model class being different than the schema of the Movie table of the database. (Il n’existe pas de colonne Rating dans la table de base de données.)(There's no Rating column in the database table.)

Plusieurs approches sont possibles pour résoudre l’erreur :There are a few approaches to resolving the error:

  1. Laisser Entity Framework supprimer et recréer automatiquement la base de données avec le nouveau schéma de classes du modèle.Have the Entity Framework automatically drop and re-create the database using the new model class schema. Cette approche est très utile au début du cycle de développement. Elle permet de faire évoluer rapidement le modèle et le schéma de base de données ensemble.This approach is convenient early in the development cycle; it allows you to quickly evolve the model and database schema together. L’inconvénient est que vous perdez les données existantes dans la base de données.The downside is that you lose existing data in the database. N’utilisez pas cette approche sur une base de données de production !Don't use this approach on a production database! La suppression de la base de données lors des changements de schéma et l’utilisation d’un initialiseur pour amorcer automatiquement la base de données avec des données de test est souvent un moyen efficace pour développer une application.Dropping the DB on schema changes and using an initializer to automatically seed the database with test data is often a productive way to develop an app.

  2. Modifiez explicitement le schéma de la base de données existante pour le faire correspondre aux classes du modèle.Explicitly modify the schema of the existing database so that it matches the model classes. L’avantage de cette approche est que vous conservez vos données.The advantage of this approach is that you keep your data. Vous pouvez apporter cette modification manuellement ou en créant un script de modification de la base de données.You can make this change either manually or by creating a database change script.

  3. Utilisez Migrations Code First pour mettre à jour le schéma de base de données.Use Code First Migrations to update the database schema.

Pour ce didacticiel, nous allons utiliser les migrations Code First.For this tutorial, use Code First Migrations.

Mettez à jour la classe SeedData pour qu’elle fournisse une valeur pour la nouvelle colonne.Update the SeedData class so that it provides a value for the new column. Vous pouvez voir un exemple de modification ci-dessous, mais elle doit être appliquée à chaque bloc new Movie.A sample change is shown below, but you'll want to make this change for each new Movie block.

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

Consultez le fichier SeedData.cs complet.See the completed SeedData.cs file.

Générez la solution.Build the solution.

Ajouter une migration pour le champ d’évaluationAdd a migration for the rating field

Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du Gestionnaire de package.From the Tools menu, select NuGet Package Manager > Package Manager Console. Dans la console du Gestionnaire de package, entrez les commandes suivantes :In the PMC, enter the following commands:

Add-Migration Rating
Update-Database

La commande Add-Migration indique au framework qu’il doit :The Add-Migration command tells the framework to:

  • Comparer le modèle Movie au schéma de base de données MovieCompare the Movie model with the Movie DB schema.
  • Créer du code pour migrer le schéma de base de données vers le nouveau modèleCreate code to migrate the DB schema to the new model.

Le nom « Rating » est arbitraire et est utilisé pour nommer le fichier de migration.The name "Rating" is arbitrary and is used to name the migration file. Il est utile d’utiliser un nom explicite pour le fichier de migration.It's helpful to use a meaningful name for the migration file.

La commande Update-Database demande à l’infrastructure d’appliquer les modifications de schéma à la base de données.The Update-Database command tells the framework to apply the schema changes to the database.

Si vous supprimez tous les enregistrements de la base de données, l’initialiseur amorce la base de données et inclut le champ Rating.If you delete all the records in the DB, the initializer will seed the DB and include the Rating field. Pour ce faire, utilisez les liens de suppression disponibles dans le navigateur ou à partir de Sql Server Object Explorer.You can do this with the delete links in the browser or from Sql Server Object Explorer (SSOX).

Une autre option consiste à supprimer la base de données et à utiliser des migrations pour recréer la base de données.Another option is to delete the database and use migrations to re-create the database. Pour supprimer la base de données dans SSOX :To delete the database in SSOX:

  • Sélectionnez la base de données dans SSOX.Select the database in SSOX.

  • Cliquez avec le bouton droit sur la base de données, puis sélectionnez Supprimer.Right click on the database, and select Delete.

  • Cochez Fermer les connexions existantes.Check Close existing connections.

  • Sélectionnez OK.Select OK.

  • Dans la console du gestionnaire de package, mettez à jour la base de données :In the PMC, update the database:

    Update-Database
    

Exécutez l’application et vérifiez que vous pouvez créer/modifier/afficher des films avec un champ Rating.Run the app and verify you can create/edit/display movies with a Rating field. Si la base de données n’est pas amorcée, définissez un point d’arrêt dans la méthode SeedData.Initialize.If the database isn't seeded, set a break point in the SeedData.Initialize method.

Ressources supplémentairesAdditional resources