Partager via


Ajout d’un nouveau champ

par Rick Anderson

Remarque

Une version mise à jour de ce didacticiel est disponible ici à l’aide de la dernière version de Visual Studio. Le nouveau tutoriel utilise ASP.NET Core MVC, qui fournit de nombreuses améliorations sur ce didacticiel.

Ce didacticiel décrit ASP.NET Core MVC avec des contrôleurs et des vues. Razor Pages est une nouvelle alternative dans ASP.NET Core, un modèle de programmation basé sur des pages qui facilite la création d’une interface utilisateur web plus facile et plus productive. Nous vous recommandons de suivre le didacticiel sur les pages Razor avant la version MVC. Le didacticiel sur les pages Razor :

  • est plus facile à suivre ;
  • couvre davantage de fonctionnalités ;
  • Est l’approche recommandée pour le développement d’applications.

Dans cette section, vous allez utiliser Migrations Entity Framework Code First pour migrer certaines modifications vers les classes de modèle afin que la modification soit appliquée à la base de données.

Par défaut, lorsque vous utilisez Entity Framework Code First pour créer automatiquement une base de données, comme vous l’avez fait précédemment dans ce didacticiel, Code First ajoute une table à la base de données pour vous aider à déterminer si le schéma de la base de données est synchronisé avec les classes de modèle à partir de laquelle elle a été générée. S’ils ne sont pas synchronisés, Entity Framework génère une erreur. Cela facilite le suivi des problèmes au moment du développement que vous pouvez trouver (par des erreurs obscures) au moment de l’exécution.

Configuration de Migrations Code First pour les modifications de modèle

Accédez à Explorateur de solutions. Cliquez avec le bouton droit sur le fichier Movies.mdf , puis sélectionnez Supprimer pour supprimer la base de données films. Si vous ne voyez pas le fichier Movies.mdf , cliquez sur l’icône Afficher tous les fichiers ci-dessous dans le contour rouge.

Capture d’écran montrant l’onglet c s du contrôleur de films et Explorateur de solutions ouvert. L’icône Afficher tous les fichiers est en rouge.

Générez l’application pour vous assurer qu’aucune erreur n’est détectée.

Dans le menu Outils, cliquez sur Gestionnaire de package NuGet, puis sur Console du Gestionnaire de package.

Ajouter Pack Man

Dans la fenêtre Gestionnaire de package console à l’invitePM>, entrez

Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext

Capture d’écran montrant la fenêtre Gestionnaire de package Console. Le texte de la commande Activer les migrations est mis en surbrillance.

La commande Enable-Migrations (illustrée ci-dessus) crée un fichier Configuration.cs dans un nouveau dossier Migrations .

Capture d’écran montrant le Explorateur de solutions. Le sous-dossier Du point de configuration c du dossier Migrations est sélectionné.

Visual Studio ouvre le fichier Configuration.cs . Remplacez la Seed méthode dans le fichier Configuration.cs par le code suivant :

protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
    context.Movies.AddOrUpdate( i => i.Title,
        new Movie
        {
            Title = "When Harry Met Sally",
            ReleaseDate = DateTime.Parse("1989-1-11"),
            Genre = "Romantic Comedy",
            Price = 7.99M
        },

         new Movie
         {
             Title = "Ghostbusters ",
             ReleaseDate = DateTime.Parse("1984-3-13"),
             Genre = "Comedy",
             Price = 8.99M
         },

         new Movie
         {
             Title = "Ghostbusters 2",
             ReleaseDate = DateTime.Parse("1986-2-23"),
             Genre = "Comedy",
             Price = 9.99M
         },

       new Movie
       {
           Title = "Rio Bravo",
           ReleaseDate = DateTime.Parse("1959-4-15"),
           Genre = "Western",
           Price = 3.99M
       }
   );
   
}

Placez le curseur sur la ligne rouge sous Movie laquelle vous cliquez, puis cliquez Show Potential Fixes sur MvcMovie.Models ;

Capture d’écran montrant le menu Afficher les correctifs potentiels. L’utilisation des modèles de point de film C M V est sélectionnée et une alerte introuvable s’affiche.

Cela ajoute l’instruction using suivante :

using MvcMovie.Models;

Remarque

Migrations Code First appelle la Seed méthode après chaque migration (autrement dit, en appelant update-database dans la console Gestionnaire de package), et cette méthode met à jour les lignes qui ont déjà été insérées ou les insère s’ils n’existent pas encore.

La méthode AddOrUpdate dans le code suivant effectue une opération « upsert » :

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

Étant donné que la méthode Seed s’exécute avec chaque migration, vous ne pouvez pas simplement insérer des données, car les lignes que vous essayez d’ajouter seront déjà là après la première migration qui crée la base de données. L’opération « upsert » empêche les erreurs qui se produisent si vous essayez d’insérer une ligne qui existe déjà, mais elle remplace les modifications apportées aux données que vous avez peut-être effectuées lors du test de l’application. Avec les données de test dans certaines tables, vous ne souhaiterez peut-être pas que cela se produise : dans certains cas, lorsque vous modifiez des données lors du test, vous souhaitez que vos modifications restent après les mises à jour de la base de données. Dans ce cas, vous souhaitez effectuer une opération d’insertion conditionnelle : insérez une ligne uniquement si elle n’existe pas déjà.

Le premier paramètre passé à la méthode AddOrUpdate spécifie la propriété à utiliser pour vérifier si une ligne existe déjà. Pour les données de film de test que vous fournissez, la Title propriété peut être utilisée à cet effet, car chaque titre de la liste est unique :

context.Movies.AddOrUpdate(i => i.Title,

Ce code suppose que les titres sont uniques. Si vous ajoutez manuellement un titre en double, vous obtenez l’exception suivante la prochaine fois que vous effectuez une migration.

Sequence contient plusieurs éléments

Pour plus d’informations sur la méthode AddOrUpdate , consultez Prendre soin d’EF 4.3 AddOrUpdate, méthode..

Appuyez sur Ctrl-Maj-B pour générer le projet.(Les étapes suivantes échouent si vous ne générez pas à ce stade.)

L’étape suivante consiste à créer une DbMigration classe pour la migration initiale. Cette migration crée une base de données, c’est pourquoi vous avez supprimé le fichier movie.mdf à l’étape précédente.

Dans la fenêtre Gestionnaire de package console, entrez la commande add-migration Initial pour créer la migration initiale. Le nom « Initial » est arbitraire et est utilisé pour nommer le fichier de migration créé.

Capture d’écran montrant la console Gestionnaire de package. Le texte de la commande ajouter une migration est mis en surbrillance.

Migrations Code First crée un autre fichier de classe dans le Dossier migrations (avec le nom {DateStamp}_Initial.cs), et cette classe contient du code qui crée le schéma de base de données. Le nom de fichier de la migration est préfixé avec un horodatage pour faciliter le classement. Examinez le fichier {DateStamp}_Initial.cs , il contient les instructions permettant de créer la Movies table pour movie DB. Lorsque vous mettez à jour la base de données dans les instructions ci-dessous, ce fichier {DateStamp}_Initial.cs s’exécute et crée le schéma de base de données. Ensuite, la méthode Seed s’exécute pour remplir la base de données avec des données de test.

Dans la console Gestionnaire de package, entrez la commande update-database pour créer la base de données et exécuter la Seed méthode.

Capture d’écran montrant la console Gestionnaire de package. La commande de base de données de mise à jour se trouve dans la fenêtre.

Si vous obtenez une erreur indiquant qu’une table existe déjà et ne peut pas être créée, c’est probablement parce que vous avez exécuté l’application après avoir supprimé la base de données et avant l’exécution update-database. Dans ce cas, supprimez à nouveau le fichier Movies.mdf et réessayez la update-database commande. Si vous obtenez toujours une erreur, supprimez le dossier des migrations et le contenu, puis commencez par les instructions en haut de cette page (c’est-à-dire supprimer le fichier Movies.mdf , puis passez à Enable-Migrations). Si vous obtenez toujours une erreur, ouvrez l’Explorateur d’objets SQL Server et supprimez la base de données de la liste. Si vous obtenez une erreur indiquant « Impossible d’attacher le fichier .mdf en tant que base de données », supprimez la propriété Catalogue initial dans le chaîne de connexion dans le fichier web.config.

Exécutez l’application et accédez à l’URL /Movies . Les données initiales sont affichées.

Capture d’écran montrant l’index vidéo M V C avec quatre films répertoriés.

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

Commencez par ajouter une nouvelle Rating propriété à la classe existante Movie . Ouvrez le fichier Models\Movie.cs et ajoutez la Rating propriété comme celle-ci :

public string Rating { get; set; }

La classe complète Movie ressemble maintenant au code suivant :

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
    public string Rating { get; set; }
}

Générez l’application (Ctrl+Maj+B).

Étant donné que vous avez ajouté un nouveau champ à la Movie classe, vous devez également mettre à jour la liste verte de liaison afin que cette nouvelle propriété soit incluse. Mettez à jour l’attribut bind et Create Edit les méthodes d’action pour inclure la Rating propriété :

[Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")]

Vous devez aussi mettre à jour les modèles de vue pour afficher, créer et modifier la nouvelle propriété Rating dans la vue du navigateur.

Ouvrez le fichier \Views\Movies\Index.cshtml et ajoutez un <th>Rating</th> en-tête de colonne juste après la colonne Price . Ajoutez ensuite une <td> colonne près de la fin du modèle pour afficher la @item.Rating valeur. Voici à quoi ressemble le modèle de vue Index.cshtml mis à jour :

@model IEnumerable<MvcMovie.Models.Movie>
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
    @Html.ActionLink("Create New", "Create")
    @using (Html.BeginForm("Index", "Movies", FormMethod.Get))
    {
    <p>
        Genre: @Html.DropDownList("movieGenre", "All")
        Title: @Html.TextBox("SearchString")
        <input type="submit" value="Filter" />
    </p>
    }
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Rating)
        </th>

        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Rating)
        </td>

        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.ID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ID })
        </td>
    </tr>
}

</table>

Ensuite, ouvrez le fichier \Views\Movies\Create.cshtml et ajoutez le Rating champ avec le balisage mis en surbrillance suivant. Cela restitue une zone de texte afin que vous puissiez spécifier une évaluation lors de la création d’un nouveau film.

<div class="form-group">
            @Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Rating, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Rating, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Rating, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Vous avez maintenant mis à jour le code de l’application pour prendre en charge la nouvelle Rating propriété.

Exécutez l’application et accédez à l’URL /Movies . Toutefois, lorsque vous effectuez cette opération, vous verrez l’une des erreurs suivantes :

Capture d’écran montrant une erreur non gérée par l’utilisateur d’exception.

Le modèle qui sauvegarde le contexte « MovieDBContext » a changé depuis la création de la base de données. Envisagez d’utiliser Migrations Code First pour mettre à jour la base de données (https://go.microsoft.com/fwlink/?LinkId=238269).

Capture d’écran montrant un navigateur avec l’erreur de serveur de notification dans l’application.

Cette erreur s’affiche, car la classe de modèle mise à jour Movie dans l’application est désormais différente du schéma de la Movie table de la base de données existante. (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. Laissez Entity Framework supprimer et recréer automatiquement la base de données sur la base du nouveau schéma de classe de modèle. Cette approche est très utile au début du cycle de développement quand vous effectuez un développement actif sur une base de données de test. Elle permet de faire évoluer rapidement le schéma de modèle et de base de données ensemble. L’inconvénient, cependant, est que vous perdez des données existantes dans la base de données . Vous ne souhaitez donc pas utiliser cette approche sur une base de données de production ! L’utilisation d’un initialiseur pour amorcer automatiquement une base de données avec des données de test est souvent un moyen efficace pour développer une application. Pour plus d’informations sur les initialiseurs de base de données Entity Framework, consultez ASP.NET didacticiel MVC/Entity Framework.
  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 vos données. Vous pouvez apporter 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 méthode Seed afin qu’elle fournisse une valeur pour la nouvelle colonne. Ouvrez le fichier Migrations\Configuration.cs et ajoutez un champ Rating à chaque objet Movie.

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

Générez la solution, puis ouvrez la fenêtre Gestionnaire de package console, puis entrez la commande suivante :

add-migration Rating

La add-migration commande indique à l’infrastructure de migration d’examiner le modèle vidéo actuel avec le schéma de base de données de film actuel et de créer le code nécessaire pour migrer la base de données vers le nouveau modèle. Le nom Rating est arbitraire et est utilisé pour nommer le fichier de migration. Il est utile d’utiliser un nom explicite pour l’étape de migration.

Une fois cette commande terminée, Visual Studio ouvre le fichier de classe qui définit la nouvelle DbMigration classe dérivée et, dans la Up méthode, vous pouvez voir le code qui crée la nouvelle colonne.

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

Générez la solution, puis entrez la update-database commande dans la fenêtre Gestionnaire de package Console.

L’image suivante montre la sortie dans la fenêtre Gestionnaire de package console (l’évaluation préliminaire de l’horodatage sera différente.)

Capture d’écran montrant la fenêtre Gestionnaire de package console avec la commande de mise à jour de la base de données entrée.

Réexécutez l’application et accédez à l’URL /Movies. Vous pouvez voir le nouveau champ Évaluation.

Capture d’écran montrant la liste M V C Movie Index avec le champ Évaluation ajouté.

Cliquez sur le lien Créer un nouveau film pour ajouter un nouveau film. Notez que vous pouvez ajouter une évaluation.

7_CreateRioII

Cliquez sur Créer. Le nouveau film, y compris l’évaluation, apparaît maintenant dans la liste des films :

7_ourNewMovie_SM

Maintenant que le projet utilise des migrations, vous n’avez pas besoin de supprimer la base de données lorsque vous ajoutez un nouveau champ ou mettez à jour le schéma. Dans la section suivante, nous allons apporter d’autres modifications de schéma et utiliser des migrations pour mettre à jour la base de données.

Vous devez également ajouter le Rating champ aux modèles d’affichage Modifier, Détails et Supprimer.

Vous pouvez entrer à nouveau la commande « update-database » dans la fenêtre Gestionnaire de package Console et aucun code de migration ne s’exécuterait, car le schéma correspond au modèle. Toutefois, l’exécution de « update-database » réexécute la Seed méthode et, si vous avez modifié l’une des données Seed, les modifications seront perdues, car la Seed méthode upserts data. Vous pouvez en savoir plus sur la méthode dans le Seed didacticiel populaire ASP.NET MVC/Entity Framework de Tom Dykstra.

Dans cette section, vous avez vu comment modifier des objets de modèle et maintenir la base de données synchronisée avec les modifications. Vous avez également appris à remplir une base de données nouvellement créée avec des exemples de données afin de pouvoir tester des scénarios. Il s’agissait simplement d’une présentation rapide de Code First, consultez Création d’un modèle de données Entity Framework pour une application MVC ASP.NET pour obtenir un didacticiel plus complet sur le sujet. Examinons ensuite comment ajouter une logique de validation plus riche aux classes de modèle et permettre à certaines règles métier d’être appliquées.