Partie 4 : Modèles et accès aux données
par Jon Galloway
Le Magasin de musique MVC est une application de tutoriel qui présente et explique pas à pas comment utiliser ASP.NET MVC et Visual Studio pour le développement web.
Le Magasin de musique MVC est un exemple d’implémentation de magasin léger qui vend des albums de musique en ligne et implémente l’administration de site de base, la connexion utilisateur et les fonctionnalités de panier d’achat.
Cette série de tutoriels détaille toutes les étapes effectuées pour générer l’exemple d’application ASP.NET magasin de musique MVC. La partie 4 traite des modèles et de l’accès aux données.
Jusqu’à présent, nous avons juste passé des « données factices » de nos contrôleurs à nos modèles d’affichage. Maintenant, nous sommes prêts à brancher une base de données réelle. Dans ce tutoriel, nous allons découvrir comment utiliser SQL Server Compact Edition (souvent appelée SQL CE) comme moteur de base de données. SQL CE est une base de données gratuite et incorporée basée sur des fichiers qui ne nécessite aucune installation ou configuration, ce qui la rend vraiment pratique pour le développement local.
Accès à la base de données avec Entity Framework Code-First
Nous allons utiliser la prise en charge d’Entity Framework (EF) incluse dans ASP.NET projets MVC 3 pour interroger et mettre à jour la base de données. EF est une API de données orm (Object Relational Mapping) flexible qui permet aux développeurs d’interroger et de mettre à jour les données stockées dans une base de données de manière orientée objet.
Entity Framework version 4 prend en charge un paradigme de développement appelé code-first. Le code-first vous permet de créer un objet de modèle en écrivant des classes simples (également appelées POCO à partir d’objets CLR simples) et peut même créer la base de données à la volée à partir de vos classes.
Modifications apportées à nos classes de modèles
Nous allons tirer parti de la fonctionnalité de création de base de données dans Entity Framework dans ce tutoriel. Avant de procéder, cependant, nous allons apporter quelques modifications mineures à nos classes de modèle pour ajouter des éléments que nous utiliserons plus tard.
Ajout des classes de modèle Artist
Nos albums étant associés à Artists, nous allons ajouter une classe de modèle simple pour décrire un artiste. Ajoutez une nouvelle classe au dossier Models nommé Artist.cs à l’aide du code ci-dessous.
namespace MvcMusicStore.Models
{
public class Artist
{
public int ArtistId { get; set; }
public string Name { get; set; }
}
}
Mise à jour de nos classes de modèles
Mettez à jour la classe Album comme indiqué ci-dessous.
namespace MvcMusicStore.Models
{
public class Album
{
public int AlbumId { get; set; }
public int GenreId { get; set; }
public int ArtistId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public Genre Genre { get; set; }
public Artist Artist { get; set; }
}
}
Ensuite, apportez les mises à jour suivantes à la classe Genre.
using System.Collections.Generic;
namespace MvcMusicStore.Models
{
public partial class Genre
{
public int GenreId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Album> Albums { get; set; }
}
}
Ajout du dossier App_Data
Nous allons ajouter un répertoire App_Data à notre projet pour contenir nos fichiers de base de données SQL Server Express. App_Data est un répertoire spécial dans ASP.NET qui dispose déjà des autorisations d’accès de sécurité appropriées pour l’accès à la base de données. Dans le menu Projet, sélectionnez Ajouter ASP.NET dossier, puis App_Data.
Création d’une chaîne de connexion dans le fichier web.config
Nous allons ajouter quelques lignes au fichier de configuration du site web afin qu’Entity Framework sache comment se connecter à notre base de données. Double-cliquez sur le fichier Web.config situé à la racine du projet.
Faites défiler jusqu’au bas de ce fichier et ajoutez une <section connectionStrings> directement au-dessus de la dernière ligne, comme indiqué ci-dessous.
<connectionStrings>
<add name="MusicStoreEntities"
connectionString="Data Source=|DataDirectory|MvcMusicStore.sdf"
providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>
</configuration>
Ajout d’une classe de contexte
Cliquez avec le bouton droit sur le dossier Modèles et ajoutez une nouvelle classe nommée MusicStoreEntities.cs.
Cette classe représente le contexte de base de données Entity Framework et gère nos opérations de création, de lecture, de mise à jour et de suppression pour nous. Le code pour cette classe est indiqué ci-dessous.
using System.Data.Entity;
namespace MvcMusicStore.Models
{
public class MusicStoreEntities : DbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Genre> Genres { get; set; }
}
}
Il n’y a pas d’autre configuration, d’interfaces spéciales, etc. En étendant la classe de base DbContext, notre classe MusicStoreEntities est en mesure de gérer nos opérations de base de données pour nous. Maintenant que nous sommes connectés, ajoutons quelques propriétés supplémentaires à nos classes de modèles pour tirer parti de certaines des informations supplémentaires de notre base de données.
Ajout de nos données de catalogue de magasins
Nous allons tirer parti d’une fonctionnalité dans Entity Framework qui ajoute des données « initiales » à une base de données nouvellement créée. Cette opération préremplira notre catalogue de magasins avec une liste de genres, d’artistes et d’albums. Le MvcMusicStore-Assets.zip téléchargement , qui comprenait nos fichiers de conception de site utilisés plus haut dans ce tutoriel, contient un fichier de classe contenant ces données initiales, situé dans un dossier nommé Code.
Dans le dossier Code/ Models, recherchez le fichier SampleData.cs et déposez-le dans le dossier Models de notre projet, comme indiqué ci-dessous.
Nous devons maintenant ajouter une ligne de code pour informer Entity Framework de cette classe SampleData. Double-cliquez sur le fichier Global.asax à la racine du projet pour l’ouvrir et ajoutez la ligne suivante en haut de la méthode Application_Start.
protected void Application_Start()
{
System.Data.Entity.Database.SetInitializer(
new MvcMusicStore.Models.SampleData());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
À ce stade, nous avons terminé le travail nécessaire pour configurer Entity Framework pour notre projet.
Interrogation de la base de données
Nous allons maintenant mettre à jour notre StoreController afin qu’au lieu d’utiliser des « données factices », il appelle à la place dans notre base de données pour interroger toutes ses informations. Nous allons commencer par déclarer un champ sur le StoreController pour contenir une instance de la classe MusicStoreEntities, nommée storeDB :
public class StoreController : Controller
{
MusicStoreEntities storeDB = new MusicStoreEntities();
Mise à jour de l’index store pour interroger la base de données
La classe MusicStoreEntities est gérée par Entity Framework et expose une propriété de collection pour chaque table de notre base de données. Mettons à jour l’action Index de StoreController pour récupérer tous les genres de notre base de données. Auparavant, nous l’avons fait en codant en dur les données de chaîne. Maintenant, nous pouvons simplement utiliser la collection Generes de contexte Entity Framework :
public ActionResult Index()
{
var genres = storeDB.Genres.ToList();
return View(genres);
}
Aucune modification n’est nécessaire pour notre modèle d’affichage, car nous renvoyons toujours le même StoreIndexViewModel que celui que nous avons retourné avant . Nous renvoyons simplement des données actives à partir de notre base de données.
Lorsque nous réexécutons le projet et accédons à l’URL « /Store », nous voyons maintenant la liste de tous les genres dans notre base de données :
Mise à jour de la navigation et des détails du magasin pour utiliser des données actives
Avec la méthode d’action /Store/Browse?genre=[some-genre], nous recherchons un genre par nom. Nous n’attendons qu’un seul résultat, car nous ne devrions jamais avoir deux entrées pour le même nom de genre, et nous pouvons donc utiliser le . Extension Single() dans LINQ pour interroger l’objet Genre approprié comme ceci (ne tapez pas encore ceci) :
var example = storeDB.Genres.Single(g => g.Name == "Disco");
La méthode Single prend une expression Lambda en tant que paramètre, qui spécifie que nous voulons un seul objet Genre afin que son nom corresponde à la valeur que nous avons définie. Dans le cas ci-dessus, nous chargeons un seul objet Genre avec une valeur Name correspondant à Disco.
Nous allons tirer parti d’une fonctionnalité Entity Framework qui nous permet d’indiquer d’autres entités associées que nous voulons également charger lors de la récupération de l’objet Genre. Cette fonctionnalité est appelée Mise en forme des résultats de requête et nous permet de réduire le nombre de fois où nous avons besoin d’accéder à la base de données pour récupérer toutes les informations dont nous avons besoin. Nous voulons pré-extraire les albums pour genre que nous récupérons. Nous allons donc mettre à jour notre requête pour inclure à partir de Genres.Include(« Albums ») pour indiquer que nous voulons également des albums associés. Cela est plus efficace, car il récupère à la fois nos données Genre et Album dans une seule demande de base de données.
Avec les explications hors de la route, voici à quoi ressemble notre action Parcourir le contrôleur mise à jour :
public ActionResult Browse(string genre)
{
// Retrieve Genre and its Associated Albums from database
var genreModel = storeDB.Genres.Include("Albums")
.Single(g => g.Name == genre);
return View(genreModel);
}
Nous pouvons maintenant mettre à jour l’affichage De navigation dans le Store pour afficher les albums disponibles dans chaque genre. Ouvrez le modèle d’affichage (trouvé dans /Views/Store/Browse.cshtml) et ajoutez une liste à puces d’Albums comme indiqué ci-dessous.
@model MvcMusicStore.Models.Genre
@{
ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
@foreach (var album in Model.Albums)
{
<li>
@album.Title
</li>
}
</ul>
L’exécution de notre application et la navigation vers /Store/Browse?genre=Jazz indique que nos résultats sont désormais extraits de la base de données, affichant tous les albums de notre genre sélectionné.
Nous allons apporter la même modification à notre URL /Store/Details/[id] et remplacer nos données factices par une requête de base de données qui charge un Album dont l’ID correspond à la valeur du paramètre.
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}
L’exécution de notre application et la navigation vers /Store/Details/1 montre que nos résultats sont désormais extraits de la base de données.
Maintenant que notre page Détails du Magasin est configurée pour afficher un album en fonction de l’ID de l’album, nous allons mettre à jour la vue Parcourir pour créer un lien vers la vue Détails. Nous allons utiliser Html.ActionLink, exactement comme nous l’avons fait pour lier l’index du Store à Store Browse à la fin de la section précédente. La source complète de la vue Parcourir apparaît ci-dessous.
@model MvcMusicStore.Models.Genre
@{
ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
@foreach (var album in Model.Albums)
{
<li>
@Html.ActionLink(album.Title,
"Details", new { id = album.AlbumId })
</li>
}
</ul>
Nous sommes désormais en mesure de naviguer à partir de notre page Store vers une page Genre, qui répertorie les albums disponibles, et en cliquant sur un album, nous pouvons afficher les détails de cet album.