Ajout d’un nouveau champ à la table et au modèle Movie
par Rick Anderson
Remarque
Une version mise à jour de ce didacticiel est disponible ici qui utilise ASP.NET MVC 5 et Visual Studio 2013. Il est plus sécurisé, beaucoup plus simple à suivre et montre plus de fonctionnalités.
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
Si vous utilisez Visual Studio 2012, double-cliquez sur le fichier Movies.mdf de Explorateur de solutions pour ouvrir l’outil de base de données. Visual Studio Express pour web affiche l’Explorateur de bases de données, Visual Studio 2012 affiche l’Explorateur de serveurs. Si vous utilisez Visual Studio 2010, utilisez l’Explorateur d’objets SQL Server.
Dans l’outil de base de données (Explorateur de bases de données, Explorateur de serveurs ou Explorateur d’objets SQL Server), cliquez avec le bouton droit sur MovieDBContext
et sélectionnez Supprimer pour supprimer la base de données de films.
Revenez à 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.
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.
Dans la fenêtre Gestionnaire de package console à l’invitePM>
, entrez « Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext ».
La commande Enable-Migrations (illustrée ci-dessus) crée un fichier Configuration.cs dans un nouveau dossier Migrations .
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
}
);
}
Cliquez avec le bouton droit sur la ligne rouge sous Movie
et sélectionnez Résoudre , puis à l’aide de MvcMovie.Models ;
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.
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 pour créer 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éé.
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 table Movies pour la base de données movie. 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 méthode Seed.
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).
Exécutez l’application et accédez à l’URL /Movies . Les données initiales sont affichées.
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; }
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 à l’aide de la commande de menu Générer>un film ou en appuyant sur Ctrl-Maj-B.
Maintenant que vous avez mis à jour la Model
classe, vous devez également mettre à jour les modèles d’affichage \Views\Movies\Index.cshtml et \Views\Movies\Create.cshtml pour afficher la nouvelle Rating
propriété dans l’affichage 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")
</p>
<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 balisage suivant à la fin du formulaire. 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="editor-label">
@Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
Vous avez maintenant mis à jour le code de l’application pour prendre en charge la nouvelle Rating
propriété.
Exécutez maintenant l’application et accédez à l’URL /Movies . Toutefois, lorsque vous effectuez cette opération, vous verrez l’une des erreurs suivantes :
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 :
- 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 pratique lors de l’exécution d’un développement actif sur une base de données de test ; il vous permet d’évoluer rapidement le modèle et le schéma 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 amorçage automatiquement une base de données avec des données de test est souvent un moyen productif de développer une application. Pour plus d’informations sur les initialiseurs de base de données Entity Framework, consultez le didacticiel ASP.NET MVC/Entity Framework de Tom Dykstra.
- 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.
- 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 = "G",
Price = 7.99M
},
Générez la solution, puis ouvrez la fenêtre Gestionnaire de package console, puis entrez la commande suivante :
add-migration AddRatingMig
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. AddRatingMig est arbitraire et sert à 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 commande « update-database » dans la fenêtre console Gestionnaire de package.
L’image suivante montre la sortie dans la fenêtre Gestionnaire de package console (l’horodatage prédéfini AddRatingMig sera différent.)
Réexécutez l’application et accédez à l’URL /Movies. Vous pouvez voir le nouveau champ Évaluation.
Cliquez sur le lien Créer un nouveau film pour ajouter un nouveau film. Notez que vous pouvez ajouter une évaluation.
Cliquez sur Créer. Le nouveau film, y compris l’évaluation, apparaît maintenant dans la liste des films :
Vous devez également ajouter le Rating
champ aux modèles d’affichage Modifier, Détails et SearchIndex.
Vous pouvez entrer à nouveau la commande « update-database » dans la fenêtre Gestionnaire de package Console et aucune modification n’est apportée, car le schéma correspond au modèle.
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. 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.