ADO.NET Entity Framework Tutorial 2 : Installation et Configuration de l’environnement

Revenir au sommaire


La configuration de votre environement de développement pour l’utilisation du framework Entity est plutôt simple.


L’entity framework ne fonctionne qu’avec un Visual Studio 2008 (2005 ne supporte pas ce framework).


Il est nécessaire de disposer du SP1. S’il est déjà installé. Vous pouvez sauter cette étape et commencer votre apprentissage. Dans le cas contraire téléchargez l’ISO ou l’exe du sp1 aux adresses suivantes :



Si vous avez précédemment installé la béta du SP1 il existe un outil de nettoyage pour votre environement qui supprimera toute référence vers cette version afin de pouvoir installer le SP1 en totu sécurité. Il est accessible ici : VS 2008 Service Pack Preparation Tool.


A noter encore, pour les développeurs de Silverlight 2b2 qu’il est nécessaire d’effectuer une reinstallation des Silverlight Tools Beta 2 pour visual studio avec un version updagrée accessible ici : Silverlight Tools Beta 2.


Terminons enfin en ajoutant qu’il existe un installeur spécifiquement dédié au framework pour les serveur à cette adresse : .NET Framework 3.5 Service pack 1.


 


Valentin Billotte


 


Revenir au sommaire

ADO.Net Data Services : Introduction

ADO.Net Data Services


Avec l’avènement des architectures distribuées, la prolifération des clients riches, qu’ils soient Desktop RDA (à base de Winforms ou WPF) ou RIA (ASP.Net AJAX ou Silverlight, Adobe AIR, …) montre le besoin en constante augmentation de systèmes d’échange de données complètements déconnectés de toute interface. Le Web 2.0 place d’ailleurs l’utilisateur au cœur du logiciel sensé le servir. Cette révolution dans la conception d’offres de services logiciels impose une architecture où là vue est indépendante de la donnée afin d’offrir à l’utilisateur une interface métier la plus riche et la plus puissante possible, elle impacte, en outre, sur la manière dont les données sont partagées et exploitées.


Le projet Astoria est un framework d’exposition d’un modèle de données au travers d’URI, respectant la philosophie REST. Il se présente comme une solution efficace, en proposant un accès simple et flexible à des sources de données par l’intermédiaire du protocole http. L’intégration avec toutes les infrastructures Web existantes est excellente et profite de mécanismes éprouvés tels que l’authentification, ou encore la mise en cache.


Là où il  apporte une grande plus value et s’avère novateur c’est que les données renvoyées par un service dépendent du besoin exprimé par la requête du client : Les URI remplacent les requêtes SQL. Nous pouvons parler alors de service générique.


 


Astoria ou la MOA générique


Exposer des données sur le Web n’est plus vraiment un problème technique aujourd’hui. Les outils Microsoft, comme visual studio aident le développeur dans la création de façade de services dites RPC (pour Remote Procedure Call). Le principe est simple, un client effectue une requête vers un « service » distant (un service SOAP par exemple ou simplement un ensemble URI) qui en réponse retourne des données. Simple certes, mais absolument pas flexible. Si le service appelé ne renvoie pas les données auquel le client s’attend, le fournisseur doit : soit modifier la fonctionnalité qu’il expose (au risque d’une incompatibilité ou d’une régression vis-à-vis de ses autres clients), ou bien exposer un nouveau service (au prix d’une redondance et d’un travail accru). Ce manque flagrant de flexibilité impacte de manière conséquente la productivité du développeur et la pérennité des applicatifs qu’il créé. Le coût pour l’entreprise est énorme. Le Framework métier exposé sur le Web dépend principalement de l’interprétation que la MOA et la MOE font de l’expression des besoins. C’est là ou se situe la problématique : imaginer l’ensemble des services répondant aux besoins de clients hétéroclites est difficile voir impossible. Cette difficulté croie en fonction de l’importance et de la complexité des données que le fournisseur veut exposer. Au final, le client se retrouve avec des données incomplètes ou inutiles et le fournisseur avec une façade de services non adaptée et en constante évolution (avec les risques qu’on connait). Si au départ, un client se met en relation avec un fournisseur c’est que celui-ci possède des données qui sont susceptible de lui servir. A tâche pour le fournisseur de lui donner un accès optimisé vers celles-ci. Avec la méthode RPC, on cherche par principe à comprendre ce que le client désire pour lui formater des services sur mesure. Le fournisseur tente d’exprimer avec justesse ce besoin, de le développer puis de l’exposer. Avec Astoria au contraire « on ne cherche rien » : On délègue à ce framework la responsabilité de comprendre votre source de données, d‘interpréter les relations qu’elle possède et surtout d’être l’interlocuteur direct entre cette source et votre client. On ne peut être mieux servi que par soit même ! Le client sait exactement ce qu’il veut : à lui d’exprimer ce besoin lorsqu’il effectue une requête vers le fournisseur, à Astoria de la comprendre et de lui renvoyer les données voulues.


Astoria un service REST-full


Astoria utilise, pour réaliser cette « prouesse »,  un service WCF générique. L’accès aux données se fait en se branchant sur l’interface IQueryable (du framework Linq). Il est donc possible d’utiliser n’importe quel provider Linq d’accès aux données (LinqToObject, LinqToXml, LinqToSql, LinqToEntities) pour exposer ses informations. Tout objet IQueryable est exposé à l’extérieur en tant qu’un ensemble entités.



La tâche du développeur est donc simple : il expose par l’intermédiaire de son service une classe ayant pour propriétés des objets IQueryable. L’EDM (pour Entity Data Model) issu du framework ADO.Net Entity possède un schéma particulièrement adapté à Astoria ; Un peu à la manière des Datasets ou de Linq to SQL, une représentation abstraite de la source de données va être généré sous la forme d’une classe qui va exposer un ensemble de propriétés IQueryable pour chaque entité.


 Le transfert des données s’appuie, tout comme le Web, sur une architecture REST (Representational State Transfer). Astoria repose donc sur les standards :


·         URI comme syntaxe universelle pour adresser les entités de manière unique.


·         HTTP un protocole avec lequel il est possible d’effectuer des opérations sur une cible


Les requêtes que l’ont adresse à un service Astoria ciblent directement une entité ou un ensemble d’entité. Voici un exemple de requête type :


http://localhost:30047/ northwind.svc/Products


Où WebDaraServices.svc est le service Astoria et « /Products » cible les produits de la table Products. Le flux retourné (en atom) serait :


<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes” ?>
<feed …>


 <id>http://localhost: 30047/northwind.svc/Products</id>


 <title>Products</title>


 <link rel=”self” href=”Products” title=”Products” />


 <entry adsm:type=”NorthwindModel.Products”>


  <id>http://host/vdir/northwind.svc/Products(1)</id>


 


  <link rel=”edit” href=”Products(1)” title=”Products” />


   <content type=”application/xml”>


   <ads:ProductID adsm:type=”Int32″>1</ads:ProductID>


   <ads:ProductName>Chai</ads:ProductName>


   <ads:QuantityPerUnit>10 boxes x 20 bags</ads:QuantityPerUnit>


  


  </content>


  <link rel=”related” title=”Categories”


              href=”Products(1)/Categories”


          type=”application/atom+xml;type=entry” />


  


 </entry>


 <entry> … </entry>


</feed>


Les balises entry contiennent les enregistrements de la table Products. Pour chaque entry, on retrouve dans la balise link, l’url pour accéder directement à l’enregistrement depuis un service Astoria. On remarque aussi qu’il existe une relation avec la table Categories. Là encore une url est spécifiée pour accéder aux catégories en rapport avec le produit courant.


Par l’intermédiaire des « verbs » http (à savoir GET, POST, PUT, DELETE) il est possible d’agir sur l’entité ou les entités ciblées par l’URL de manière à :


·         Créer des entités


·         Consulter les entités


·         Mettre à jour des entités


·         Supprimer des entités


 Associés à une requête ils permettent d’agir sur la ressource visée par une URI. Il est possible enfin de profiter du type MIME pour associer au flux retourné au client le type/formatage des données. L’accès aux entité doit respecter une syntaxe d’Url précise. Par exemple :


§  Ensemble d’Entités : http://server/Users


§  Entité simple : …/Users(123)


§  Accès à une valeur : …/Users(123)/Name


§  Lien relationnel : …/Users(123)/Tags


§  Accès à une valeur via une jointure : …/Users(123)/Tags(abc)/Name


§  Accès à une valeur brute : …/Users(123)/Names/$value


§  Tri : …/Users?$orderedby=Name


§  Filtre : …/Users?$filter=Created gt’2007-05-07 ‘


§  Pagination : …/Users?$top=10&$skip=30


§  Accès à des informations détaillées : …/Users?$expand=Tags


La création d’un tel service se fait très facilement. Microsoft associe une classe au service automatiquement formatée, laissant le soin au développeur de préciser la classe à exposer et les droits d’accès vers les entités qu’elle contient :


namespace SimpleDataService
{
    public class Northwind : WebDataService<NorthwindEntities>
    {
        public static void
             InitializeService(IWebDataServiceConfiguration config)
        {
            config.SetResourceContainerAccessRule(“*”,
                                ResourceContainerRights.All);
        }
    }
}


Ici la classe exposée se nomme NorthwindEntities. La méthode InitializeService est appelée automatiquement au premier accès vers le service. Elle permet de préciser les droits d’accès vers les entités de la classe. Pour permettre la modification les données (répondre à POST, PUT et DELETE), il faut implémenter dans la classe exposée, l’interface IUpdatable.


Coté client l’intérêt d’Astoria est évident, on s’adresse aux services par une simple requête http. Le format des données échangées peut être au choix, en POX (Plein Old Xml) –prévu pour la version finale-, JSON (Javascript Objet Notation), ou ATOM (format de syndication). Soit un ensemble de formats standardisés et pérennes. Tous comme les Web Services ou WCF les services Astoria sont utilisables depuis n’importe quelle technologie (bien que les développeurs Microsoft, soient légèrement favorisés -voir encadré).


Contrôler les accès aux données


L’exposition sur un réseau de données de manière générique requiert une bonne sécurisation de l’accès aux services et un contrôle accru sur ce qui est échangé. Astoria s’intègre parfaitement avec ASP.NET. Ce qui veut dire que les systèmes d’authentification basé sur http comme le « forms authentication », l’ « integrated authentication » ou encore le« basic authentication » sont gérés parfaitement. Il peut être aussi nécessaire de sécuriser de manière plus fine l’échange de données afin de bloquer des modifications sur des entités ou bien de modifier le flux des données renvoyées au client. La classe utilisée derrière votre service Astoria possède une méthode statique qui est automatiquement appelée au lancement de l’application. Elle permet de définir les autorisations d’accès vers les entités exposées.


config.SetResourceContainerAccessRule(“Products”, ResourceContainerRights.All);


config.SetResourceContainerAccessRule(“Categories”, ResourceContainerRights.AllRead);


Ici le jeu d’entité Categories n’est accessible qu’en lecture alors que toutes les opérations CRUD sont autorisées pour Products. Il est possible d’intercepter l’expression Linq (non encore exécutée puisqu’on échange de l’IQueryable) afin de la modifier pour effectuer un filtre (par exemple en fonction des droits de l’utilisateur).


[QueryInterceptor("Products")]
public IQueryable<Products> InterceptProducts(
  IQueryable< Products > incomingQuery)
{
  incomingQuery = incomingQuery.Take(5);
  return incomingQuery;
}


La méthode ci-dessus, insérée dans la classe du service, intercepte les requêtes vers la table Products et la modifie de sorte à ne renvoyer que les 5 premiers résultats. Le développeur peut aussi implémenter ses propres méthodes d’accès aux données en les préfixant par l’attribut :


 [WebGet]
 public static IQueryable<Customer> CustomersByCity(NorthwindEntities db, string city)
{
   if (city == null || city.Length < 3)
      throw new Exception(“bad city”);

   var q = db.Customers.Where(“it.City = @city”, new ObjectParameter(“city”, city));

   return q;
 }


Bien entendu, la méthode renvoie de l’IQueryable. Elle serait accessible via une url du type :


  /MyCustomersByCity?city=Sarcelles


Séparer le modèle de données, l’accès, et la vue.


Une application Web traditionnelle fonctionne à peu près toujours sur le même principe : un jeu de pages et de scripts coté serveur qui sont exécutés à chaque requête. La source de données est questionnée et un habillage HTML généré qui contiendra a la fois des données de présentation et des données métier.



(((Legende)))
A chaque requêtes sont échangés données et présentation


Les dernières technologies de conception d’interface utilisateur introduisent le besoin d’émanciper la donnée de sa vue afin d’apporter une nouvelle approche : les données de présentations sont envoyées au client distinctement des données métier.



(((Legende)))
Après « réception » de la vue, seules les données sont échangées. Le client peut alors communiquer avec différentes sources de données.


Lorsque la vue est chargée sur le client, les seules données échangées entre le client et le serveur sont les données métier. Si dans les applications traditionnelles, l’obtention de données résultait d’une collaboration entre le serveur Web et le serveur de base de données, cette nouvelle approche dans la conception d’application fait que le serveur Web n’a plus un rôle primordial. On peut alors découper l’architecture en deux partie : l’interface utilisateur et la source de donnée qu’elle manipule. C’est là ou Astoria tire son épingle du jeu. Son arrivée synchrone avec Silverlight 2.0 n’est pas un hasard.


Quand le réseau, devient plateforme


Avec Live Mesh (plateforme de stockage en lien avec un support de synchronisation), SQL Server Data Service (base de données en ligne) et ADO.NET Data services, Microsoft avance à grand pas sur sa stratégie Software + Services (autre manière de parler du SaaS – Software As A Service).


  Il s’agit de faire du réseau un fournisseur de services et plus seulement un moyen physique de faire transiter des données. Astoria a donc vocation d’être un incontournable de toute infrastructure informatique « à la demande ». Astoria favorise ainsi la création d’applications composites mash-up, et contribue à orienter le système d’information vers une architecture de services où les clients riches tissent des liens sur le réseau vers des services de données hétéroclites, formatent les données puisées de manière à répondre au besoin spécifique du client : c’est ça l’informatique à la demande.


 


 (((Encadré)))


Linq, le VIP Astoria ?


Si les services Astoria sont utilisables depuis n’importe quelle technologie capable d’émettre des requêtes http, les développeurs Microsoft sont privilégiés : Astoria s’accompagne d’outils qui permettent notamment de générer les classes proxies pour accéder aux services exposés. Il est alors possible de s’inter opérer avec les données exposées par le service Astoria en Linq ! Ce “LinqToHttp” ou Linq déporté, communique avec un WebDataContext (à l’instar du DataContext de Linq To Sql ou de l’ObjectContext de l’entity framework). Via ce proxy, les requêtes Linq sont sérialisées en URL syntaxe compréhensible par le service Astoria. En retour Astoria, via le proxy renvoie un ensemble de données sous la forme d’un objet IQueryable. L’accès aux données distantes se fait alors de manière totalement transparente :


WebDataContext context = new WebDataContext(“http://localhost:30047/Northwind.svc”);


 


            var query = from p in context.CreateQuery<Product>(“Products”)


                        select p;


 


            foreach (Product p in query)


            {


                //traitement


            }

Incompatibilité entre Silverlight 2b2 et Ado.Net Data Services avec le framework 3.5 SP1

L’installation du SP1 (VS 2008 SP1 et/ou framework 3.5 sp1) empêche les développements Software + Services entre Silverlight et ADO.Net Data services (Astoria). Deux bugs apparaissent :


                                                                         



Dans le cas où le Xap Silverlight se trouve sur le même domaine que les services Astoria vous optenez l’erreur suivante :


“Aucun constructeur sans paramètre défini pour cet objet.” 


 {System.MissingMethodException: Aucun constructeur sans paramètre défini pour cet objet.
   à System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
   à System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
   à System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)


 


 Dans le cas où Silverlight se trouve sur un autre domaine une autre erreur apparait sur l’appel à EndExecute après une requête Linq to Data services. :


System.InvalidOperationException occurred
  Message=”Failed to Invoke: callOpen.”
  StackTrace:
       at System.Windows.Browser.ScriptObject.Invoke(String name, Object[] args)
       at System.Data.Services.Http.ScriptObjectUtility.CallOpen(ScriptObject request, String method, String uri)
       at System.Data.Services.Http.HttpWebRequest.ScriptXmlHttpRequest.Open(Boolean async, String url, String method, Action OnReadyStateChange)
       at System.Data.Services.Http.HttpWebRequest.InvokeRequest(Boolean async)


 


La réponse de Pablo Castro à ce soucis est sans équivoque :


“Unfortunately, due to work arounds required for other aspects of Data Services functionality, cross-domain access is not supported in the Data Services client included in Silverlight Beta 2. We’re working to sort out the issue for the RTM release.”


                                                                         


En gros il faudra attendre la sortie de la rtm de Silverlight pour voir ces deux problèmes corrigés (prévu pour la fin de l’été, soit … bientôt). D’ici là les équipes travaillant sur ces produits se contenteront d’un développement MVC en ne travaillant que sur la vue coté software et que sur les fonctionnalités métier coté services… en attendant de pouvoir relier le tout.


Plus d’infos sur :


http://blogs.msdn.com/astoriateam/archive/2008/08/12/compat-note-silverlight-beta-2-client-net-framework-3-5-sp1-server-components.aspx


 


(c’est quand même fou de voir de tels oublis/lacunes sur deux produits aussi liés …)

Pourquoi je m’oriente vers Silverlight

Depuis mes débuts en développement j’ai toujours fait du lourd. Entendez par là du client Lourd. A savoir du Winform principalement, de l’API Win 32 et  du Xna. J’ai commencé à aborder WPF il y’a deux ans. J’ai rapidement abandonné cette technologie estimant qu’elle n’avait pas un bel avenir devant elle. Je trouve qu’elle est extraordinaire et parfaitement bien conçue, mais elle ne répond pas au futur des besoins que demanderons les applicatifs dans les mois à venir.



Avant SIlverlight 2.0 bx, le plugin de Microsoft etait plus un jouet qu’un outil professionnel. Il montrait avec force ce qu’allait être Silverilght et ce que nous allions pouvoir en faire. Il manquait encore un grand nombre de fonctionnalités, les fonctionnalités existantes n’étaient pas pérennes et les outils de développements associés n’était pas forcement stables…



L’arrive des 2.0 bx change la donne. Il s’agit d’un version reconnue par Microsoft comme étant Go Live. Microsoft s’engage donc a fournir un support et donc à ce qu’une société puisse répondre à ses exigences métier et graphique via cette technologie. C’est le point important à avoir en tête. Bien entendu Silverlight est un sous ensemble de WPF. Je suis tout à fait conscient qu’un développement graphique avec WPF ne sera pas forcement plus rapide mais utilisera des technologies Built in que nous n’auront pas coté Silverlight. Le développeur aura ainsi à travailler coté code .net là où avec WPF il aurait opéré coté Xaml. Je ne pense pas que ce soit réellement handicapant.


Ce qui me pousse vers Silverlight c’est d’imaginer l’avenir proche. Les applications lourdes vont progressivement péricliter sans toutefois disparaitre. La plupart des utilisateurs seront connectés à Internet à souhait depuis leur téléphone portable (chez orange Internet illimité c’est 6 euros par mois, les principaux opérateurs lancent même des mini pc uniquement dédiés à Internet). Ce qui sera important sur un ordinateur ce n’est plus son système d’exploitation mais son browser. Sa capacité à profiter d’internet et surtout les plugins qu’il peut recevoir. Il fut un temps où Microsoft n’avait pas peur d’offrir des API non multi plateforme obligeant les applicatifs à ne tourner que sous un Windows xXx. Face à ce changement majeur de mentalité, des technologies comme l’API Win 32, WinForm, et même WPF prennent un gout amer. On entend toujours parler d’une bataille entre le monde Windows et le monde Unix. Mais pour la plupart des Internautes ce combat est complètement inintéressant et dépassés ; Ce qu’ils recherchent avant tout c’est comment lancer le navigateur pour accéder aux sites de communautés, pour accéder aux mails, aux sites de recherche, etc. Si bien que ces derniers temps, on parlait plus de la bataille entre Internet Explorer 8 et le dernier Mozilla. Les deux sociétés derrière ces navigateurs rivalisent d’ingéniosité pour offrir plus de services aux utilisateurs. C’est seulement le browser qui donnera une chance pour l’internaute lambda de rester sur un système d’exploitation. Windows a encore de beaux jours devant lui grâce à la politique Marketing de Microsoft et parce que, en entreprise, le parc d’applications lourdes tournant sous son système est important. Ajoutons à cela que les outils de développement qu’elle offre sont les plus efficaces. Mais cet aspect des choses n’aura aucun intérêt pour les milliards d’internautes à venir qui utiliseront le réseau des réseaux.


Utiliser Internet se fait depuis n’importe quel système d’exploitation, depuis n’importe quel mobile, depuis n’importe quelle borne d’accès de n’importe quelle galerie commerciale. Plus une société offrira un moyen d’exploiter Internet de manière intelligente plus son avenir est assuré. Les IPhones de Mac, le futur portable de Google. Microsoft toujours numéro en terme de système d’exploitation mobile avec Windows Mobile va rapidement placer Silverlight sur ce créneau là pour suivre le mouvement. Ce que Microsoft anticipe aussi c’est le besoin d’applications riches composées d’une couche vue et d’une couche controleur sans aucune spécification d’accès aux données. Il estime aussi un autre besoin important : internet en tant que plateforme de service et non plate forme réseau. Une infinité de services sur Internet auxquels les applicatifs riches vont le connecter pour remplir leur interface. Un tel système applicatif suivra toujours la même procédure : l’utilisateur télécharge l’application depuis le browser (pour Silverilght un Xap) de manière transparente. Le browser lance l’application, l’application s’initialise, charge son interface et se connecte à différents agrégats de services (ou mashups) pour remplir son contenu. L’interaction avec les services se fait via cette interface réglementée et offerte par le fournisseur. Google place son modèle économique là dessus. Nombre de ses services sont gratuits… mais limités. Chacun d’eux amène sur un autre service …  limité. Le tout entrecoupé de publicités. L’accès à des services plus complet sera bien évidemment payant. Microsoft ne peut plus se baser uniquement sur son modèle économique à base de Windows et D’Office mais doit suivre ce modèle.


On ne doit pas limiter un applicatif et l’accès à des services à une configuration de machine on doit la rendre accessible sans limites (je n’inclus pas ici les aspects commerciaux dans le “sans limites”). WPF peut être très utile dans le cadre de besoins bien précis. Là ou le besoin de technologies que le browser et ses plugins ne peuvent pas offrir. Je pense à la 3D, je pense au mode offline (bien que le terme offline risque de devenir rapidement désuet avec Live Mesh) ou bien encore des outils de développement. Je verrais plus ce type d’applicatifs “ponctuels” en WPF qu’en Silverlight.


La conclusion de tout cela c’est que pour faire connaitre une application et pour toucher un maximum de personne ce n’est plus au développement Windows qu’il faut penser mais au développement RIAs. Dans ce domaine, Silverlight avec la technologie .Net les environnements de développement Microsoft et Windows Mobile a une réelle carte à jouer. Ajoutons qu’avec Live Mesh (plateforme de stockage en lien avec un support de synchronisation), SQL Server Data Service (base de données en ligne) et ADO.NET Data services, Microsoft avance à grand pas sur sa stratégie Software + Services (autre manière de parler du SaaS – Software As A Service).


  Il s’agit de faire du réseau un fournisseur de services et plus seulement un moyen physique de faire transiter des données. Tout cela contribue à orienter le système d’information vers une architecture de services où les clients riches tissent des liens sur le réseau vers des services de données hétéroclites, formatent les données puisées de manière à répondre au besoin spécifique du client : c’est ça l’informatique à la demande.



Aujourd’hui mes technologies de prediclections passent par Silverlight, le Framework Entity, ADO.NET Data Services et Xna (for ever :) )

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