IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

MVC Music Store

MVC Music Store


précédentsommairesuivant

IV.1. Introduction

Jusqu'à présent, nous passions des "données factices " depuis nos contrôleurs à nos vues. Maintenant nous sommes prêts à relier une vraie base de données. Dans ce tutoriel nous allons voir comment utiliser SQL Server Compact Edition (souvent appelé SQL CE) comme moteur de base de données. SQL CE est une base de données gratuite et embarquée, qui ne nécessite pas d'installation ou configuration, ce qui la rend très pratique pour le développement local.

IV.2. Accès à la base de données avec Entity Framework Code-First

Nous allons utiliser Entity Framework (EF) qui est inclus dans les projets ASP.NET MVC 3 pour interroger et mettre à jour la base de données. EF est un mapping objet-relationnel flexible (ORM) qui permet aux développeurs d'interroger et mettre à jour des données stockées dans une base de données d'une manière orientée objet.

La version 4 d'Entity Framework supporte un paradigme de développement appelé code-first. Code-first nous permet de créer un modèle objet en écrivant de simples classes (également connu comme POCO du "plain-old" CLR objects), et peut même créer la base de données à la volée à partir de vos classes.

IV.2.1. Modifications de nos classes modèles

Nous bénéficierons de la fonctionnalité de création de la base de données d'Entity Framework dans ce tutoriel. Avant cela, cependant, effectuons quelques changements mineurs à nos classes modèles en ajoutant certaines choses que nous utiliserons plus tard.

IV.2.2. Ajout de la classe modèle Artist

Nos albums vont être associés aux artistes, nous allons donc ajouter une simple classe modèle correspondant à un artiste. Ajoutez une nouvelle classe au dossier Models appelée Artist.cs en utilisant le code ci-dessous.

 
Sélectionnez
namespace MvcMusicStore.Models
{
    public class Artist
    {
        public int ArtistId { get; set; }
        public string Name { get; set; }
    }
}

IV.2.3. Mise à jour de nos classes modèles

Mettez à jour la classe Album comme indiqué ci-dessous.

 
Sélectionnez
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, effectuez les changements suivants à la classe Genre.

 
Sélectionnez
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; }
    }
}

IV.2.4. Ajout du dossier App_Data

Nous allons ajouter un dossier App_Data à notre projet qui accueillera la base de données SQL Server Express. App_Data est un dossier spécial d'ASP.NET qui contient déjà les autorisations correctes pour l'accès à la base de données. Depuis le menu Project, sélectionnez Add ASP.NET Folder, puis App_Data.

Image non disponible

IV.2.5. Création de la chaîne de connexion dans le fichier web.config

Nous allons ajouter quelques lignes dans le fichier de configuration du site web de sorte qu'Entity Framework sache comment se connecter à la base de données. Double-cliquez sur le fichier Web.config situé à la racine du projet.

Image non disponible

Faites défiler vers le bas de ce fichier et ajoutez une section <connectionStrings> directement au-dessus de la dernière ligne, comme suit.

 
Sélectionnez
					  <connectionStrings>
					    <add name="MusicStoreEntities"
					     connectionString="Data Source=|DataDirectory|MvcMusicStore.sdf"
					     providerName="System.Data.SqlServerCe.4.0"/>
					  </connectionStrings>  
					</configuration>

IV.2.6. Ajout d'une classe Context

Faites un clic-droit sur le dossier Models et ajoutez une nouvelle classe appelée MusicStoreEntities.cs.

Image non disponible

Cette classe va représenter le contexte de base de données Entity Framework, et va s'occuper des opérations de création, lecture, mise à jour, et suppression pour nous. Voici le code de cette classe.

 
Sélectionnez
using System.Data.Entity;
 
namespace MvcMusicStore.Models
{
    public class MusicStoreEntities : DbContext
    {
        public DbSet<Album> Albums { get; set; }
        public DbSet<Genre> Genres { get; set; }
    }
}

C'est tout - il n'y a pas d'autre configuration, interfaces spéciales, etc. En étendant la classe de base DbContext, notre classe MusicStoreEntities est capable de gérer les opérations de base de données pour nous. Maintenant que nous l'avons attachée à DbContext, nous allons ajouter quelques propriétés supplémentaires à nos classes modèles pour profiter de quelques informations supplémentaires dans notre base de données.

IV.2.7. Ajout de données au catalogue du magasin

Nous allons profiter d'une fonctionnalité d'Entity Framework qui ajoute des données de "semence" à une base de données fraîchement créée. Cela va pré-peupler notre catalogue avec une liste de Genres, Artistes, et Albums. Le fichier MvcMusicStore-Assets.zip - qui comprend les fichiers de conception du site utilisé plus tôt dans ce tutoriel - contient une classe avec les données de semence, situé dans un dossier appelé Code.

Dans le dossier Code / Models, trouvez le fichier SampleData.cs et déposez le dans le dossier Models de notre projet, comme ci-dessous.

Image non disponible

Maintenant il nous faut ajouter une ligne de code pour informer Entity Framework de la présence de la classe SampleData. Double-cliquez sur le fichier Global.asax dans la racine du projet pour l'ouvrir et ajoutez la ligne suivante au début de la méthode Application_Start.

 
Sélectionnez
protected void Application_Start()
{
    System.Data.Entity.Database.SetInitializer(
                new MvcMusicStore.Models.SampleData());
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
 }

A cet instant, nous avons terminé les travaux nécessaires pour configurer Entity Framework pour notre projet.

IV.3. Interroger la base de données

Nous allons actualiser notre StoreController de sorte qu'au lieu d'utiliser des "données factices" il interroge la base de données pour obtenir les informations. Nous allons commencer par déclarer un champ dans le StoreController qui va récupérer une instance de la classe MusicStoreEntities, appelé storeDB :

 
Sélectionnez
public class StoreController : Controller
{
    MusicStoreEntities storeDB = new MusicStoreEntities();

IV.3.1. Mettre à jour l'Index du Store pour interroger la base de données

La classe MusicStoreEntities est maintenue par Entity Framework et expose une propriété collection pour chaque table de notre base. Mettons à jour la méthode Index du StoreController pour retrouver tous les Genres de notre base. Précédemment nous l'avions fait en codant en dur une chaîne. Maintenant, nous pouvons simplement utiliser le contexte d'Entity Framework qui génère une collection à la place :

 
Sélectionnez
public ActionResult Index()
{
    var genres = storeDB.Genres.ToList();
    return View(genres);
 }

Il n'y a pas de changement à apporter à notre Vue puisque nous retournons toujours le même StoreIndexViewModel qu'auparavant - nous renvoyons juste des données en direct de notre base maintenant.

Lorsque l'on exécute à nouveau le projet et que l'on va sur l'URL "/Store", nous pourrons voir une liste de tous les Genres de notre base de données :

Image non disponible

IV.3.2. Mise à jour des vues Browse et Details du Store pour utiliser des données en direct

Dans l'action /Store/Browse?genre=[some-genre], nous recherchons un Genre par nom. Nous ne prévoyons qu'un seul résultat, puisque nous ne devrions jamais avoir 2 entrées pour un même nom, et donc nous pouvons utiliser l'extension LINQ .Single() pour interroger l'objet Genre approprié comme ceci (ne l'écrivez pas encore) :

 
Sélectionnez
var example = storeDB.Genres.Single(g => g.Name == "Disco");

La méthode Single prend une expression Lambda en paramètre, qui spécifie que nous voulons un unique objet Genre tel que son nom corresponde à la valeur que nous avons définie. Dans le cas ci-dessus, nous chargeons un objet Genre avec la valeur Disco pour le Name.

Nous allons profiter d'une fonctionnalité d'Entity Framework qui nous permet d'indiquer d'autres entités liées que nous voulons aussi bien charger lorsque l'objet Genre est retrouvé. Cette fonctionnalité est appelée Query Result Shaping, et nous permet de réduire le nombre de fois que nous avons besoin d'accéder à la base pour retrouver toutes les informations dont nous avons besoin. Nous voulons pré-extraire les Albums pour le Genre que nous récupérons, donc nous allons mettre à jour notre requête avec Genres.Include("Albums") pour indiquer que nous voulons aussi les albums liés. C'est plus efficace, car il va récupérer les données du Genre et de l'Album à l'aide d'une seule requête en base.

Une fois débarrassés des explications, voici comment l'action Browse du contrôleur mise à jour ressemble :

 
Sélectionnez
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 la vue Browse du Store pour afficher les albums qui sont disponibles dans chaque Genre. Ouvrez la vue (qui se trouve dans /Views/Store/Browse.cshtml) et ajoutez une liste à puces d'albums comme suit.

 
Sélectionnez
@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>

Le fait d'exécuter notre application et d'aller sur l'url /Store/Browse?genre=Jazz nous montre que nos résultats sont extraits de la base, et affichent tous les albums du Genre sélectionné.

Image non disponible

Nous allons faire la même modification pour l'URL /Store/Details/[id], et remplacer nos données actuelles par une requête en base qui va charger un Album dont l'ID correspond à la valeur du paramètre.

 
Sélectionnez
public ActionResult Details(int id)
 {
    var album = storeDB.Albums.Find(id);
 
    return View(album);
 }

Exécuter l'application et aller sur l'url /Store/Details/1 montre que nos résultats sont désormais extraits de la base.

Image non disponible

Maintenant que notre page Details du Store est configurée pour afficher un album grace à son ID, mettons à jour la vue Browse pour la relier à la vue Details. Nous allons utiliser un Html.ActionLink, exactement comme nous l'avions fait pour relier la page Index du Store à la page Browse du Store à la fin du précédent chapitre. Le code source complet de la vue Browse devrait apparaître comme suit.

 
Sélectionnez
@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 maintenant en mesure de naviguer depuis notre page Store vers la page Genre, qui liste les albums disponibles, et en cliquant sur un album nous pouvons voir les détails de l'album en question.

Image non disponible

Vous pouvez utiliser les discussions disponibles sur http://mvcmusicstore.codeplex.com pour toutes questions ou tous commentaires.


précédentsommairesuivant

Copyright © 2012 Jon Galloway. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.