Partie 2 : Création des modèles de domaine

par Rick Anderson

Télécharger le projet terminé

Ajouter des modèles

Il existe trois façons d’aborder Entity Framework :

  • Base de données d’abord : vous commencez par une base de données et Entity Framework génère le code.
  • Modèle d’abord : vous commencez par un modèle visuel, et Entity Framework génère à la fois la base de données et le code.
  • Code-first : vous commencez par du code et Entity Framework génère la base de données.

Comme nous utilisons l’approche code-first, nous commençons par définir nos objets de domaine en tant que POC (objets CLR simples). Avec l’approche code-first, les objets de domaine n’ont pas besoin de code supplémentaire pour prendre en charge la couche de base de données, comme les transactions ou la persistance. (Plus précisément, ils n’ont pas besoin d’hériter de la classe EntityObject .) Vous pouvez toujours utiliser des annotations de données pour contrôler la façon dont Entity Framework crée le schéma de base de données.

Étant donné que les objets de concept n’ont pas de propriétés supplémentaires qui décrivent l’état de la base de données, ils peuvent facilement être sérialisés au format JSON ou XML. Toutefois, cela ne signifie pas que vous devez toujours exposer vos modèles Entity Framework directement aux clients, comme nous le verrons plus loin dans le tutoriel.

Nous allons créer les POC suivants :

  • Produit
  • Commande
  • OrderDetail

Pour créer chaque classe, cliquez avec le bouton droit sur le dossier Models dans Explorateur de solutions. Dans le menu contextuel, sélectionnez Ajouter , puis Classe.

Capture d’écran du menu Explorer Solutions pour le dossier Modèles. Le menu Ajouter est ouvert et l’option Classe est mise en surbrillance.

Ajoutez une Product classe avec l’implémentation suivante :

namespace ProductStore.Models
{
    using System.ComponentModel.DataAnnotations;

    public class Product
    {
        [ScaffoldColumn(false)]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public decimal Price { get; set; }
        public decimal ActualCost { get; set; }
    }
}

Par convention, Entity Framework utilise la Id propriété comme clé primaire et la mappe à une colonne d’identité dans la table de base de données. Lorsque vous créez un Product instance, vous ne définissez pas de valeur pour Id, car la base de données génère la valeur.

L’attribut ScaffoldColumn indique ASP.NET MVC d’ignorer la propriété lors de la Id génération d’un formulaire d’éditeur. L’attribut Required est utilisé pour valider le modèle. Elle spécifie que la Name propriété doit être une chaîne non vide.

Ajoutez la Order classe :

namespace ProductStore.Models
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public class Order
    {
        public int Id { get; set; }
        [Required]
        public string Customer { get; set; }

        // Navigation property
        public  ICollection<OrderDetail> OrderDetails { get; set; }
    }
}

Ajoutez la OrderDetail classe :

namespace ProductStore.Models
{
    public class OrderDetail
    {
        public int Id { get; set; }
        public int Quantity { get; set; }
        public int OrderId { get; set; }
        public int ProductId { get; set; }

        // Navigation properties
        public Product Product { get; set; }
        public Order Order { get; set; }
    }
}

Relations de clé étrangère

Une commande contient de nombreux détails de commande, et chaque détail de commande fait référence à un seul produit. Pour représenter ces relations, la classe définit des OrderDetail propriétés nommées OrderId et ProductId. Entity Framework déduit que ces propriétés représentent des clés étrangères et ajoute des contraintes de clé étrangère à la base de données.

Capture d’écran des menus Visual Studio pour les classes Orders, Products et OrderDetails.

Les Order classes et OrderDetail incluent également des propriétés de « navigation », qui contiennent des références aux objets associés. Pour une commande, vous pouvez accéder aux produits dans l’ordre en suivant les propriétés de navigation.

Compilez le projet maintenant. Entity Framework utilise la réflexion pour découvrir les propriétés des modèles. Elle nécessite donc un assembly compilé pour créer le schéma de base de données.

Configurer les formateurs Media-Type

Un formateur de type média est un objet qui sérialise vos données lorsque l’API web écrit le corps de la réponse HTTP. Les formateurs intégrés prennent en charge la sortie JSON et XML. Par défaut, ces deux formateurs sérialisent tous les objets par valeur.

La sérialisation par valeur crée un problème si un graphique d’objet contient des références circulaires. C’est exactement le cas avec les Order classes et OrderDetail , car chacune contient une référence à l’autre. Le formateur suit les références, écrit chaque objet par valeur et tourne en rond. Par conséquent, nous devons modifier le comportement par défaut.

Dans Explorateur de solutions, développez le dossier App_Start et ouvrez le fichier nommé WebApiConfig.cs. Ajoutez le code suivant à la classe WebApiConfig :

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // New code:
        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling =
            Newtonsoft.Json.PreserveReferencesHandling.Objects;

        config.Formatters.Remove(config.Formatters.XmlFormatter);
    }
}

Ce code définit le formateur JSON pour conserver les références d’objet et supprime entièrement le formateur XML du pipeline. (Vous pouvez configurer le formateur XML pour conserver les références d’objets, mais c’est un peu plus de travail, et nous n’avons besoin que de JSON pour cette application. Pour plus d’informations, consultez Gestion des références d’objets circulaires.)