Partager via


Ajout d’un nouveau champ

par Rick Anderson

Notes

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 par rapport à ce tutoriel.

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 rend la création d’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 préférée pour le développement de nouvelles applications.

Dans cette section, vous allez utiliser Migrations Entity Framework Code First pour migrer certaines modifications apportées aux 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 lève une erreur. Cela facilite le suivi des problèmes au moment du développement que vous ne trouverez sinon que (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 et sélectionnez Supprimer pour supprimer la base de données movies. 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 Dot c s du contrôleur de films et Explorateur de solutions ouvert. L’icône Afficher tous les fichiers est cerclée 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 Console du Gestionnaire de package à l’invite PM> , entrez

Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext

Capture d’écran montrant la fenêtre Console du Gestionnaire de package. 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 Configuration dot c s 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
       }
   );
   
}

Pointez sur la ligne rouge et cliquez sur MovieMvcMovie.Models, puis cliquez Show Potential Fixes sur MvcMovie.Models ;

Capture d’écran montrant le menu Afficher les correctifs potentiels. L’utilisation de M V C Movie dot Models est sélectionnée et une alerte introuvable s’affiche.

Cette opération ajoute l’instruction using suivante :

using MvcMovie.Models;

Notes

Migrations Code First appelle la Seed méthode après chaque migration (c’est-à-dire, en appelant update-database dans la console du Gestionnaire de package), et cette méthode met à jour les lignes qui ont déjà été insérées ou les insère si elles 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 toutes les modifications apportées aux données que vous avez pu apporter lors du test de l’application. Avec des données de test dans certaines tables, vous pouvez ne pas souhaiter que cela se produise : dans certains cas, lorsque vous modifiez des données pendant le 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 case activée 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 obtiendrez l’exception suivante la prochaine fois que vous effectuerez une migration.

La séquence contient plusieurs éléments

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

Appuyez sur CTRL-MAJ-B pour générer le projet.(Les étapes suivantes échoueront 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 Console du Gestionnaire de package, 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 du 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 (sous le nom {DateStamp}_Initial.cs ), et cette classe contient le code qui crée le schéma de base de données. Le nom de fichier de migration est prédéfini avec un horodatage pour faciliter le classement. Examinez le fichier {DateStamp} _Initial.cs . Il contient les instructions de création de la Movies table pour la base de données 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 du 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 du Gestionnaire de package. La commande update database se trouve dans la fenêtre.

Si vous recevez 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 la suppression de 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 et le contenu des migrations, puis commencez par les instructions en haut de cette page (c’est-à-dire supprimer le fichier Movies.mdf , puis passer à Enable-Migrations). Si vous obtenez toujours une erreur, ouvrez SQL Server Explorateur d'objets 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 cadre de la chaîne de connexion dans le fichier web.config .

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

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 pour Create et 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 champ avec le Rating balisage suivant en surbrillance. Cela restitue une zone de texte afin que vous puissiez spécifier une évaluation lors de la création d’une nouvelle vidéo.

<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, l’une des erreurs suivantes s’affiche :

Capture d’écran montrant une erreur d’utilisateur d’exception non prise en charge.

Le modèle qui sauvegarde le contexte « MovieDBContext » a changé depuis la création de la base de données. Utilisez 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 du serveur de notification dans l’application.

Vous voyez cette erreur, 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 tutoriel 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, ouvrez la fenêtre Console du Gestionnaire de package et 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 vidéo 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 Console du Gestionnaire de package.

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

Capture d’écran montrant la fenêtre Console du Gestionnaire de package avec la commande update database 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 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 que vous mettez à jour le schéma. Dans la section suivante, nous allons apporter d’autres modifications au 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 à nouveau entrer la commande « update-database » dans la fenêtre Console du Gestionnaire de package 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écutera 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. Pour plus d’informations sur la méthode, consultez le Seeddidacticiel 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 synchronisation de la base de données 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 essayer des scénarios. Il s’agit d’une introduction rapide à Code First. Pour obtenir un didacticiel plus complet sur le sujet, consultez Création d’un modèle de données Entity Framework pour une application MVC ASP.NET . Voyons ensuite comment ajouter une logique de validation plus riche aux classes de modèle et permettre l’application de certaines règles d’entreprise.