ADO.NET Entity Framework

Revenir au sommaire


Le Framework Entity de Microsoft  est une technologie intégrée à ADO.Net qui aide au développement d’application spécialisées dans la manipulation de données. Les architectes et les développeurs doivent à la fois modéliser le besoin métier sur laquelle porte la problématique de ces applications, sous la forme d’entités, de relations, d’intégrité et respecter les contraintes liés au stockage de ces données pour les manipuler.


Le framework Entity vise à permettre aux  développeurs de travailler sur des objets métiers proches de la conceptualisation sémantique que la maitrise d’œuvre peut en faire en l’éloignant des spécificités techniques liées à leur stockage. Pour permettre ça le Framework Entity propose une couche d’abstraction malléable à souhait entre la couche de stockage et la couche métier. Il évite en outre toutes les tâches fastidieuses et sensibles liées à la manipulation et aux échanges de données.


Le MCD au cœur du développement


Le modèle de données d’une application peut être divisé en trois parties bien distinctes :


  • Le modèle conceptuel (MCD).
  • Le modèle logique.
  • Le modèle physique.

Le modèle physique n’intéresse en rien le développeur. C’est le domaine réservé de l’administration de la base. Il vise l’étude des besoins de données et la réponse adéquat à ces besoins sous la formes d’indexes, de partitions afin d’améliorer les performances dans la manipulation des données. Le modèle conceptuel définit les entités et leurs relations. Enfin le modèle logique (dans le cas d’une base relationnelle) normalise entités et relations sous la forme de tables, de clés étrangères et de contraintes.


En caricaturant un peu on peut alors dire que :


·         Le modèle physique ne concerne que les administrateurs de la base.


·         Le modèle logique ne concerne que les développeurs. Leurs interractions avec ce modèle se limitant généralement à des requêtes sql et des appels à des procédures stockées.


·         Le modèle conceptuel enfin est le domaine de la maitrise d’ouvrage qui conceptualise le besoin métier.


On peut définir alors une loi “mathématiquo-informatique” bien connue : « plus le développeur s’éloigne du modèle conceptuel avec un modèle logique compliqué, plus le temps de développement et le besoin de maintenance est important ».


La manipulation de données par un modèle de programmation orienté objet pose d’un réel problème dans l’interaction avec le système de stockage de données. Généralement, dans le cas de base de données relationnelle,  on associe à une classe métier (par exemple Customers) une table avec le même nom dans la base. Mais la symbiose n’est pas forcement parfaite. Il arrive ainsi que plusieurs  tables dans la base correspondent à une seule classe (et inversement). On trouve cette problématique généralement dans le cadre d’un héritage. Une classe Customers peut hériter d’une classe User. Comment simplement relier ces objets métiers à la couche logique de la base de données sous jacente qui utilise à la fois une table User et une table Customer reliées par une clé étrangère ? Un autre problème porte sur les relations entre les tables. Regardez les tables Customers  et la table Order de la base d’exemple AdventureWorks et les classes objets de même nom qui en découlent. Pour lier un ordre d’achat à un client, la classe Order utilisera une propriété qui contenant une référence vers une instance de la classe Customer. Rien de bien compliqué puisque coté modèle logique, la table Order contient une clé étrangère dont la valeur correspond à la clé primaire de la table Customer. Inversement, une instance de la classe Customer doit pouvoir être relié à l’ensemble de ses achats (liste d’instances de la classe Order). Malheureusement coté modèle logique la table Customer n’a pas de colonne permettant une telle reliaison. Ce ne sont là que deux exemples parmi une infinité d’autres mettant en évidence la difficulté de faire cohabiter dans un projet le modèle conceptuel et le modèle logique.


Ces différences entre logique et conceptuel sont généralement appelés  (désolé pour la francisation) « décallage d’impédance » (pour « Impedance mismatch »).


Nombre de solutions existent pour passer du modèle logique à un modèle objet (Strongly Typed Dataset, Dataset, Code Smith, …). Ces méthodes consistent bien souvent simplement à relier une classe et ses propriétés à une table et ses colonnes. Le tout en ajoutant quelques traitements simples liés à une analyse sémantique rudimentaire. Le gain pour le développeur est assez limité. Il évite l’écriture des classes et quelques opérations CRUD basiques (Create, Read, Update, Delete) mais il est souvent obligé d’encapsuler le modèle généré d’un grand nombre de fonctionnalités non cohérentes et lourdes pour tenter d’approcher au maximum le modèle conceptuel.


L’approche du Framework Entity est différente. Il part du modèle logique et offre les moyens d’interpoler la transition entre conceptuel et logique. Il effectue pour cela trois itérations. Tout d’abord, à la manière classique d’un dataset, il effectue des relations simples entre une table et une classe, une colonne et une prorpriété et une clé étrangère et la classe associée. Il étudie ensuite les relations entre les table et stockent les informations liées à celles ci. Enfin il “trace” un lien entre les relations et les classes impactées. Ainsi le framework est capable de lier le modèle objet au plus prêt du modèle logique en leur donnant un traitement interne intelligente tout en restant fidèle au modèle conceptuel.


Lorsque l’entity framework doit générer une classe objet à partir d’une table lambda il sait quelles propriétés elles utilise, quels autres objects métiers elle référence et quels autres objets métiers référencent cette classe. L’entity framework permet enfin, au développeur, de participer au workflow de génération des classes en leur ajoutant des métadatas permettant de rendre le modèle objet en sortie réellement “métier”.


Les classes générées sont déclarée « partial » : les développeurs peuvent les étendre à souhait en ajoutant des propriétés et des fonctionnalités qui ne peuvent pas être “calculées” à partir du modèle logique de la source de données. Ces classes héritent en outre de classes spéciales du framework Entity qui leur offre un appareillage efficace pour passer au travers du « décalage d’impédance » entre logique et conceptuel et surtout pour calculer et supprimer le delta existant entre la représentation des données dans le système de stockage et ces mêmes données dans le modèle objet actuellement manipulés dans l’application. Ces classes spéciales appartiennent à une couche spécifique du framework Entity nommée « Object Services ». C’est à l’aide des fonctionnalités de cette couche que le développeur va actualier un objet, le descendre dans la couche objet, le supprimer, etc.


Pour terminer, le framework Entity rend le modèle conceptuel « interractif » et « portable » : Interractif d’abord puisqu’il offre aux développeurs la possibilité d’effectuer des requêtes sur les entités et leurs relations en transcrivant ces requêtes en un ensemble de commandes compréhensibles pour la sous de données sous jacente (Sql dans le cas d’une base de données). Le développeur connaissant la technologie Linq y verra là un intérêt particulier. De ceci découle la portabilité. En laissant au framework le soin de construire lui-même les commandes on devient indépendant de la plateforme de stockage des données.



EDM (Entity Data Model)


Nous parlions de trois itérations dans le point précédent pour l’étude du modèle conceptuel à partir du modèle logique. Ces itérations sont exprimées sous la forme de fichiers de spécifications Xml qu’on appelle l’Entity Data Model ou EDM. Ce dernier est donc défini par trois fichiers :


·         Un fichier .csdl pour la définition du schéma conceptuel de données (Conceptuel schema definition language file).


·         Un fichier .ssdl pour la définition du schéma logique des données (Store schema définition file)


·         Un fichier .msl de cartographie pour exprimer les liens entre les deux modèles (Mapping specification language file).


Il est possible de générer ces fichiers de plusieurs manières. Nous verrons cela plus tard. Pour l’heure, il faut comprendre que les fichiers exprimant le modèle logique (ssdl) et la cartographique (msl)  peuvent être modifiés au besoin sans toucher au fichier conceptuel (csdl). Ainsi on s’adapte au besoin aux évolutions de la source de données sans pour autant modifier les classes générées et surtout, sans modifier le code de l’application. On rejoint alors la notion de portabilité du point précédent. Le modèle logique où sont stockées les données dépend fortement du fournisseur de données utilisé. Il est au final possible de travailler sur un modèle conceptuel directement sans se soucier de ces éléments techniques. Le gain de temps de développement, le gain de temps en maintenance applicative, et la pérennités des productions se voit décuplé.


Microsoft offre deux moyens de générer l’EDM.  Les deux partent de la base pour effectuer leur traitement. Il est d’abord possible d’utiliser l’IDE visual studio, qui, à l’aide d’un Wizard, vous aiguillera dans les différentes étapes qui mènent à l’EDM et au modèle objet généré. Le second en utilisant un utilitaire en ligne de commande nommé edmgen.exe qui, appellé avec les bon paramètres générera lui aussi l’EDM et les classes liées. 


 Deux façons de générer l'EDM


Dans le premier cas, Visual Studio genera un fichier edmx qui contiendra l’ensemble des trois fichiers EDM (.csdl, .ssdl et .msl). Dans le second cas, l’utilitaire generera trois fichiers distincts. Le fichier edmx est peut être plus “propre” et simple d’utilisation, mais il n’est pas aussi maléable que les trois fichiers séparés. En outre, les opérations que le développeur peut réaliser à la main sur son contenu sont limitées.



Travailler avec les données


Comment interagir avec la couche métier générée par le framework Entity et par extension les données liées ? Les classes de la couche Object Services dont nous avons parlé précédemment utilisent les spécifications EDM pour traduire les requêtes métiers liées au modèle conceptuel en requêtes spécifiquement adaptées à la couche de stockage de données. Inversement, le résultat de ces requêtes est interpolé en un jeu d’objets manipulés par la couche Object Services. Il est possible de requêter le modèle conceptuel de trois façon :


·         Par l’intermédiaire de Linq to Entities, un provider Language-Integrated-Query (Linq) spécifiquement dédié au requêtage de modèles conceptuels.


·         Via Entity Sql, un Sql abstrait indépendant du fournisseur de données qui lui aussi travaille directement avec le modèle conceptuel.


·         A l’aide du Query Builder, un outil qui permet de construire des requêtes compatible Entity Sql sous un style assez proche des requêtes Linq.


Les requêtes issues de la couche Object Services sont gérées par l’EntityClient data provider. Celui-ci s’occupe des connexions vers la source de données, de la transformation des reqêtes en langage abstrait en requêtes adaptées à la source de données et renvoie un data reader que la couche Object Services peut manipuler. L’entityClient data provider se base sur l’EDM pour comprendre les relations entre conceptuel et logique et répondre aux exigence des requêtes formulées par l’application.


L’image suivante illustre l’architecture :


Architecture du framework Entity



Terminons en abordant rapidement  ObjectContext. Cette classe représente l’ensemble des données représentées par le modèle Conceptuel à un instant T. C’est par elle que s’effectuent les opérations de type CRUD et les échanges entre les objets métiers et la couche Object Services. L’objetcontext permet d’eviter de descendre dans les couches basses de l’architecture lorsque celà n’est pas nécessaire (pourquoi rappatrier des données de la base pour un objet qui a déjà été chargé ?).


Une révolution dans la manipulation de données


L’entity framework est un réel atout pour tout développeur travaillant sur des appications essentiellement tournées vers la manipulation de données. Il offre des moyens builtin, eprouvés et efficaces pour travailler à haut niveau sur des entités proches de l’expression de besoins métiers que la MOA peut en faire. Les développements peuvent ainsi s’adapter rapidement et sans contraintes à toute exigence métier sans avoir à se soucier de leur implémentation technique et des évolutions liées telle qu’une architecture logicielle peut en subir. Il s’agit en outre d’un moyen très efficace, couplé avec ADO.Net Data Services pour exposer des données facilement, rapidement et proprement sur le Web en lieu et places des sempiternels Web Services qui semblent désormais dépassés. On ne peut regretter qu’une chose, qu’aucun outil générant des diagrammes de classe (Visual Studio, Visio)  utilisés par la MOA ne puisse générer automatiquement les fichiers csdl :).



Valentin Billotte


 Revenir au sommaire

8 thoughts on “ADO.NET Entity Framework”

  1. Plutot sympa ton explication. Je cherchais une méthode pour pouvoir séparer l’ensemble des fichiers générés par ADO.Net et tu es le premier à (enfin) aborder le sujet.
    Merci ^^

  2. Excelent sujet, nous avions développés la même avec la même logique il y’a quelque temps dans ma boite, et ça nous a pris un temps fous.
    Si à l’époque il y’avait ça, ça nous aurrait évité pas mal de prise de tête.

    ;-)

  3. Salut,

    Désolé de déterrer ce post mais je ne saisis pas trop ce qu’apporte l’Entity Framework…

    Imagines, d’un côté je génère un DataContext avec le concepteur objet/relationnel et je manipule ensuite mes données avec un peu de Linq To SQL. De l’autre côté, j’utilise l’Entity Framework.

    J’ai testé les deux méthodes et je trouve la première solution bien plus facile à mettre en place. Bon ok, mon projet de test n’était surement pas très représentatif de ce qu’on peut rencontrer dans le monde pro, mais bon…

    Tu pourrais m’éclairer ?

    Merci !

  4. L’entity framework permet de créer une vue métier très haut niveau portable et deconnecté de problématiques techniques (comment l’accès à une base). On est proche de spécifications métier.

    Linq to sql est bas niveau, plus dur à maintenir et un risque de génèrer un code assez sale.

  5. Ok donc même si ça peut sembler lourd au premier coup d’oeil, y’a un vrai gain de productivité au final.

    Merci bien pour les explications :)

  6. Salut !
    Bien que trop en retard dans la suite de cette serie de question-reponse mais j’espère au moin à une reponse… merci !
    Je travail actuellement sur un truc de ce genre, je envie de compredre.
    Quel place occupe Entity Framework par rapport à Linq ? je fais du Linq franchement, j’suis pas gater bien que il ya encore des blème avec Linq…
    Qu’en dis-tu, sur les modification de la BD avec Entity Framework? Le gain de temps en dev avec Linq est considérable tout de même.
    ‘Te lire bientôt !

  7. Linq permet de réaliser des requêtes sur des agrégats de données en C#

    EF framework est un système qui permet de passer du modèle logique d’une base de données à un modèle conceptuel proche des specifications métiers. Il n’y a donc pas de rapport direct. Simplement, le modèle conceptuel généré par EF possède des collections IQueryable “attaquable” en linq.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>