Partie 7, ajouter un nouveau champ à une page Razor dans ASP.NET Core

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 8 de cet article.

Par Rick Anderson

Dans cette section, Migrations Entity Framework Code First est utilisé pour :

  • Ajouter un nouveau champ au modèle.
  • Migrer la nouvelle modification du schéma des champs vers la base de données.

Quand vous utilisez EF Code First pour créer et suivre automatiquement une base de données, 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é.
  • Lève une exception si les classes de modèle ne sont pas synchronisées avec la base de données.

La vérification automatique de la synchronisation du schéma et du modèle facilite la recherche de problèmes de code de base de données incohérents.

Ajout d’une propriété Rating au modèle Movie

  1. Ouvrez le fichier Models/Movie.cs et ajoutez une propriété Rating :

    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Modifiez Pages/Movies/Index.cshtml, puis ajoutez un champRating :

    @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>
    
  3. Mettez à jour les pages suivantes avec un champ Rating :

L’application ne fonctionne pas tant que la base de données n’est pas mise à jour pour inclure le nouveau champ. L’exécution de l’application sans mise à jour de la base de données lève un SqlException :

SqlException: Invalid column name 'Rating'.

Cette exception SqlException est due au fait que la classe du modèle Film mise à jour est différente du schéma de la table Film de la base de données. Il n’existe pas de colonne Rating dans la table de base de données.

Plusieurs approches sont possibles pour résoudre l’erreur :

  1. Laisser Entity Framework supprimer et recréer automatiquement la base de données avec le nouveau schéma de classes du modèle. Cette approche est très utile au début du cycle de développement. Elle permet au développeur de faire évoluer rapidement le modèle et le schéma de base de données ensemble. L’inconvénient est que les données existantes dans la base de données sont perdues. N’utilisez pas cette approche sur une base de données de production ! 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.
  2. Modifier explicitement le schéma de la base de données existante pour le faire correspondre aux classes du modèle. L’avantage de cette approche est que vous conservez les données. Apportez cette modification manuellement ou en créant un script de modification de la base de données.
  3. Utilisez les migrations Code First pour mettre à jour le schéma de base de données.

Pour ce didacticiel, nous allons utiliser les migrations Code First.

Mettez à jour la classe SeedData pour qu’elle fournisse une valeur pour la nouvelle colonne. Vous pouvez voir un exemple de modification ci-dessous, mais appliquez cette modification à chaque bloc new Movie.

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.

Générer l’application

Appuyez sur Ctrl+Maj+B

Ajouter une migration pour le champ d’évaluation

  1. Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package.

  2. Dans la console du gestionnaire de package, entrez les commandes suivantes :

    Add-Migration Rating
    Update-Database
    

La commande Add-Migration indique au framework qu’il doit :

  • Comparer le modèle Movie au schéma de base de données Movie.
  • Créer du code pour migrer le schéma de base de données vers le nouveau modèle.

Le nom « Rating » est arbitraire et utilisé pour nommer le fichier de migration. Il est utile d’utiliser un nom explicite pour le fichier de migration.

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.

Supprimez tous les enregistrements de la base de données, l’initialiseur amorce la base de données et inclut le champ Rating. La suppression peut ce faire en utilisant les liens de suppression disponibles dans le navigateur ou à partir de 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. Pour supprimer la base de données dans SSOX :

  1. Sélectionnez la base de données dans SSOX.

  2. Cliquez avec le bouton droit sur la base de données, puis sélectionnez Supprimer.

  3. Cochez Fermer les connexions existantes.

  4. Sélectionnez OK.

  5. Dans la console du gestionnaire de package, mettez à jour la base de données :

    Update-Database
    

Exécutez l’application et vérifiez que vous pouvez créer/modifier/afficher des films avec un champ Rating. Si la base de données n’est pas amorcée, définissez un point d’arrêt dans la méthode SeedData.Initialize.

Étapes suivantes

Dans cette section, Migrations Entity Framework Code First est utilisé pour :

  • Ajouter un nouveau champ au modèle.
  • Migrer la nouvelle modification du schéma des champs vers la base de données.

Quand vous utilisez EF Code First pour créer et suivre automatiquement une base de données, 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é.
  • Lève une exception si les classes de modèle ne sont pas synchronisées avec la base de données.

La vérification automatique de la synchronisation du schéma et du modèle facilite la recherche de problèmes de code de base de données incohérents.

Ajout d’une propriété Rating au modèle Movie

  1. Ouvrez le fichier Models/Movie.cs et ajoutez une propriété Rating :

    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Modifiez Pages/Movies/Index.cshtml, puis ajoutez un champRating :

    @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>
    
  3. Mettez à jour les pages suivantes avec un champ Rating :

L’application ne fonctionne pas tant que la base de données n’est pas mise à jour pour inclure le nouveau champ. L’exécution de l’application sans mise à jour de la base de données lève un SqlException :

SqlException: Invalid column name 'Rating'.

Cette exception SqlException est due au fait que la classe du modèle Film mise à jour est différente du schéma de la table Film de la base de données. Il n’existe pas de colonne Rating dans la table de base de données.

Plusieurs approches sont possibles pour résoudre l’erreur :

  1. Laisser Entity Framework supprimer et recréer automatiquement la base de données avec le nouveau schéma de classes du modèle. Cette approche est très utile au début du cycle de développement. Elle permet au développeur de faire évoluer rapidement le modèle et le schéma de base de données ensemble. L’inconvénient est que les données existantes dans la base de données sont perdues. N’utilisez pas cette approche sur une base de données de production ! 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.
  2. Modifier explicitement le schéma de la base de données existante pour le faire correspondre aux classes du modèle. L’avantage de cette approche est que vous conservez les données. Apportez cette modification manuellement ou en créant un script de modification de la base de données.
  3. Utilisez les migrations Code First pour mettre à jour le schéma de base de données.

Pour ce didacticiel, nous allons utiliser les migrations Code First.

Mettez à jour la classe SeedData pour qu’elle fournisse une valeur pour la nouvelle colonne. Vous pouvez voir un exemple de modification ci-dessous, mais appliquez cette modification à chaque bloc new Movie.

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.

Générer l’application

Appuyez sur Ctrl+Maj+B

Ajouter une migration pour le champ d’évaluation

  1. Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package.

  2. Dans la console du gestionnaire de package, entrez les commandes suivantes :

    Add-Migration Rating
    Update-Database
    

La commande Add-Migration indique au framework qu’il doit :

  • Comparer le modèle Movie au schéma de base de données Movie.
  • Créer du code pour migrer le schéma de base de données vers le nouveau modèle.

Le nom « Rating » est arbitraire et utilisé pour nommer le fichier de migration. Il est utile d’utiliser un nom explicite pour le fichier de migration.

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.

Supprimez tous les enregistrements de la base de données, l’initialiseur amorce la base de données et inclut le champ Rating. La suppression peut ce faire en utilisant les liens de suppression disponibles dans le navigateur ou à partir de 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. Pour supprimer la base de données dans SSOX :

  1. Sélectionnez la base de données dans SSOX.

  2. Cliquez avec le bouton droit sur la base de données, puis sélectionnez Supprimer.

  3. Cochez Fermer les connexions existantes.

  4. Sélectionnez OK.

  5. Dans la console du gestionnaire de package, mettez à jour la base de données :

    Update-Database
    

Exécutez l’application et vérifiez que vous pouvez créer/modifier/afficher des films avec un champ Rating. Si la base de données n’est pas amorcée, définissez un point d’arrêt dans la méthode SeedData.Initialize.

Étapes suivantes

Dans cette section, Migrations Entity Framework Code First est utilisé pour :

  • Ajouter un nouveau champ au modèle.
  • Migrer la nouvelle modification du schéma des champs vers la base de données.

Quand vous utilisez EF Code First pour créer et suivre automatiquement une base de données, 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é.
  • Lève une exception si les classes de modèle ne sont pas synchronisées avec la base de données.

La vérification automatique de la synchronisation du schéma et du modèle facilite la recherche de problèmes de code de base de données incohérents.

Ajout d’une propriété Rating au modèle Movie

  1. Ouvrez le fichier Models/Movie.cs et ajoutez une propriété Rating :

    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; } = string.Empty;
    
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; } = string.Empty;
    
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
        public string Rating { get; set; } = string.Empty;
    }
    
  2. Modifiez Pages/Movies/Index.cshtml, puis ajoutez un champRating :

    @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>
    
  3. Mettez à jour les pages suivantes avec un champ Rating :

L’application ne fonctionne pas tant que la base de données n’est pas mise à jour pour inclure le nouveau champ. L’exécution de l’application sans mise à jour de la base de données lève un SqlException :

SqlException: Invalid column name 'Rating'.

Cette exception SqlException est due au fait que la classe du modèle Film mise à jour est différente du schéma de la table Film de la base de données. Il n’existe pas de colonne Rating dans la table de base de données.

Plusieurs approches sont possibles pour résoudre l’erreur :

  1. Laisser Entity Framework supprimer et recréer automatiquement la base de données avec le nouveau schéma de classes du modèle. Cette approche est très utile au début du cycle de développement. Elle permet au développeur de faire évoluer rapidement le modèle et le schéma de base de données ensemble. L’inconvénient est que les données existantes dans la base de données sont perdues. N’utilisez pas cette approche sur une base de données de production ! 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.
  2. Modifier explicitement le schéma de la base de données existante pour le faire correspondre aux classes du modèle. L’avantage de cette approche est que vous conservez les données. Apportez cette modification manuellement ou en créant un script de modification de la base de données.
  3. Utilisez les migrations Code First pour mettre à jour le schéma de base de données.

Pour ce didacticiel, nous allons utiliser les migrations Code First.

Mettez à jour la classe SeedData pour qu’elle fournisse une valeur pour la nouvelle colonne. Vous pouvez voir un exemple de modification ci-dessous, mais appliquez cette modification à chaque bloc new Movie.

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.

Générez la solution.

Ajouter une migration pour le champ d’évaluation

  1. Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package.

  2. Dans la console du gestionnaire de package, entrez les commandes suivantes :

    Add-Migration Rating
    Update-Database
    

La commande Add-Migration indique au framework qu’il doit :

  • Comparer le modèle Movie au schéma de base de données Movie.
  • Créer du code pour migrer le schéma de base de données vers le nouveau modèle.

Le nom « Rating » est arbitraire et utilisé pour nommer le fichier de migration. Il est utile d’utiliser un nom explicite pour le fichier de migration.

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.

Supprimez tous les enregistrements de la base de données, l’initialiseur amorce la base de données et inclut le champ Rating. La suppression peut ce faire en utilisant les liens de suppression disponibles dans le navigateur ou à partir de 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. Pour supprimer la base de données dans SSOX :

  1. Sélectionnez la base de données dans SSOX.

  2. Cliquez avec le bouton droit sur la base de données, puis sélectionnez Supprimer.

  3. Cochez Fermer les connexions existantes.

  4. Sélectionnez OK.

  5. Dans la console du gestionnaire de package, mettez à jour la base de données :

    Update-Database
    

Exécutez l’application et vérifiez que vous pouvez créer/modifier/afficher des films avec un champ Rating. Si la base de données n’est pas amorcée, définissez un point d’arrêt dans la méthode SeedData.Initialize.

Étapes suivantes

Affichez ou téléchargez un exemple de code (procédure de téléchargement).

Dans cette section, Migrations Entity Framework Code First est utilisé pour :

  • Ajouter un nouveau champ au modèle.
  • Migrer la nouvelle modification du schéma des champs vers la base de données.

Quand vous utilisez EF Code First pour créer automatiquement une base de données, 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é.
  • Si les classes de modèle ne sont pas synchronisées avec la base de données, EF lève une exception.

La vérification automatique de la synchronisation du schéma et du modèle facilite la recherche de problèmes de code de base de données incohérents.

Ajout d’une propriété Rating au modèle Movie

  1. Ouvrez le fichier Models/Movie.cs et ajoutez une propriété Rating :

    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; }
    }
    
  2. Générez l'application.

  3. Modifiez Pages/Movies/Index.cshtml, puis ajoutez un champ Rating :

    @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>
    
  4. Mettez à jour les pages suivantes avec un champ Rating :

L’application ne fonctionne pas tant que la base de données n’est pas mise à jour pour inclure le nouveau champ. L’exécution de l’application sans mise à jour de la base de données lève un SqlException :

SqlException: Invalid column name 'Rating'.

Cette exception SqlException est due au fait que la classe du modèle Film mise à jour est différente du schéma de la table Film de la base de données. Il n’existe pas de colonne Rating dans la table de base de données.

Plusieurs approches sont possibles pour résoudre l’erreur :

  1. Laisser Entity Framework supprimer et recréer automatiquement la base de données avec le nouveau schéma de classes du modèle. 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. L’inconvénient est que vous perdez les données existantes dans la base de données. N’utilisez pas cette approche sur une base de données de production ! 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.

  2. Modifier explicitement le schéma de la base de données existante pour le faire correspondre aux classes du modèle. L’avantage de cette approche est que vous conservez les données. Apportez cette modification manuellement ou en créant un script de modification de la base de données.

  3. Utilisez les migrations Code First pour mettre à jour le schéma de base de données.

Pour ce didacticiel, nous allons utiliser les migrations Code First.

Mettez à jour la classe SeedData pour qu’elle fournisse une valeur pour la nouvelle colonne. Vous pouvez voir un exemple de modification ci-dessous, mais appliquez cette modification à chaque bloc new Movie.

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.

Générez la solution.

Ajouter une migration pour le champ d’évaluation

  1. Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package.

  2. Dans la console du gestionnaire de package, entrez les commandes suivantes :

    Add-Migration Rating
    Update-Database
    

La commande Add-Migration indique au framework qu’il doit :

  • Comparer le modèle Movie au schéma de base de données Movie.
  • Créer du code pour migrer le schéma de base de données vers le nouveau modèle.

Le nom « Rating » est arbitraire et utilisé pour nommer le fichier de migration. Il est utile d’utiliser un nom explicite pour le fichier de migration.

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.

Supprimez tous les enregistrements de la base de données, l’initialiseur amorce la base de données et inclut le champ Rating. La suppression peut ce faire en utilisant les liens de suppression disponibles dans le navigateur ou à partir de 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. Pour supprimer la base de données dans SSOX :

  1. Sélectionnez la base de données dans SSOX.

  2. Cliquez avec le bouton droit sur la base de données, puis sélectionnez Supprimer.

  3. Cochez Fermer les connexions existantes.

  4. Sélectionnez OK.

  5. Dans la console du gestionnaire de package, mettez à jour la base de données :

    Update-Database
    

Exécutez l’application et vérifiez que vous pouvez créer/modifier/afficher des films avec un champ Rating. Si la base de données n’est pas amorcée, définissez un point d’arrêt dans la méthode SeedData.Initialize.

Étapes suivantes

Affichez ou téléchargez un exemple de code (procédure de téléchargement).

Dans cette section, Migrations Entity Framework Code First est utilisé pour :

  • Ajouter un nouveau champ au modèle.
  • Migrer la nouvelle modification du schéma des champs vers la base de données.

Quand vous utilisez EF Code First pour créer automatiquement une base de données, 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é.
  • Si les classes de modèle ne sont pas synchronisées avec la base de données, EF lève une exception.

La vérification automatique de la synchronisation du schéma et du modèle facilite la recherche de problèmes de code de base de données incohérents.

Ajout d’une propriété Rating au modèle Movie

  1. Ouvrez le fichier Models/Movie.cs et ajoutez une propriété Rating :

    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; }
    }
    
  2. Générez l'application.

  3. Modifiez Pages/Movies/Index.cshtml, puis ajoutez un champ Rating :

    @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>
    
  4. Mettez à jour les pages suivantes avec un champ Rating :

L’application ne fonctionne pas tant que la base de données n’est pas mise à jour pour inclure le nouveau champ. L’exécution de l’application sans mise à jour de la base de données lève un SqlException :

SqlException: Invalid column name 'Rating'.

Cette exception SqlException est due au fait que la classe du modèle Film mise à jour est différente du schéma de la table Film de la base de données. Il n’existe pas de colonne Rating dans la table de base de données.

Plusieurs approches sont possibles pour résoudre l’erreur :

  1. Laisser Entity Framework supprimer et recréer automatiquement la base de données avec le nouveau schéma de classes du modèle. 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. L’inconvénient est que vous perdez les données existantes dans la base de données. N’utilisez pas cette approche sur une base de données de production ! 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.

  2. Modifier explicitement le schéma de la base de données existante pour le faire correspondre aux classes du modèle. L’avantage de cette approche est que vous conservez les données. Apportez cette modification manuellement ou en créant un script de modification de la base de données.

  3. Utilisez les migrations Code First pour mettre à jour le schéma de base de données.

Pour ce didacticiel, nous allons utiliser les migrations Code First.

Mettez à jour la classe SeedData pour qu’elle fournisse une valeur pour la nouvelle colonne. Vous pouvez voir un exemple de modification ci-dessous, mais appliquez cette modification à chaque bloc new Movie.

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.

Générez la solution.

Ajouter une migration pour le champ d’évaluation

  1. Dans le menu Outils, sélectionnez Gestionnaire de package NuGet > Console du gestionnaire de package.

  2. Dans la console du gestionnaire de package, entrez les commandes suivantes :

    Add-Migration Rating
    Update-Database
    

La commande Add-Migration indique au framework qu’il doit :

  • Comparer le modèle Movie au schéma de base de données Movie.
  • Créer du code pour migrer le schéma de base de données vers le nouveau modèle.

Le nom « Rating » est arbitraire et utilisé pour nommer le fichier de migration. Il est utile d’utiliser un nom explicite pour le fichier de migration.

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.

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. Pour ce faire, utilisez les liens de suppression disponibles dans le navigateur ou à partir de Sql Server Object Explorer.

Une autre option consiste à supprimer la base de données et à utiliser des migrations pour recréer la base de données. Pour supprimer la base de données dans SSOX :

  • Sélectionnez la base de données dans SSOX.

  • Cliquez avec le bouton droit sur la base de données, puis sélectionnez Supprimer.

  • Cochez Fermer les connexions existantes.

  • Sélectionnez OK.

  • Dans la console du gestionnaire de package, mettez à jour la base de données :

    Update-Database
    

Exécutez l’application et vérifiez que vous pouvez créer/modifier/afficher des films avec un champ Rating. Si la base de données n’est pas amorcée, définissez un point d’arrêt dans la méthode SeedData.Initialize.

Étapes suivantes