Cet article est une introduction Entity Framework, l'outil de mapping objet-relationnel de Microsoft.
Avant-Propos................................................................................................................................................................ 3 Prrequis logiciels........................................................................................................................................................ 4 1 - Concept d'Entity Framework.................................................................................................................................. 5 1.1 - Les entits..................................................................................................................................................... 6 1.2 - Object Services..............................................................................................................................................7 1.3 - Quels sont les SGBDR supports ?..............................................................................................................7 1.4 - L'diteur de modle EDM..............................................................................................................................8 2 - Conception d'un modle EDM............................................................................................................................. 10 2.1 - L'hritage..................................................................................................................................................... 13 2.1.1 - Une table par type d'entit..................................................................................................................14 2.1.2 - Une seule table pour toutes les entits.............................................................................................. 16 2.2 - Les procdures stockes.............................................................................................................................18 2.2.1 - Import de fonctions..............................................................................................................................19 2.2.2 - Cration, mise jour et suppression d'entits....................................................................................19 2.3 - Une entit pour 2 tables..............................................................................................................................21 2.4 - Les types complexes................................................................................................................................... 23 3 - Utilisation des entits et du contexte...................................................................................................................25 3.1 - Oprations CRUD........................................................................................................................................25 3.1.1 - Lecture des donnes...........................................................................................................................25 3.1.2 - Cration, mise jour et suppression.................................................................................................. 27 3.2 - Personnalisation...........................................................................................................................................28 3.2.1 - Les classes entits..............................................................................................................................28 3.2.2 - La classe de contexte......................................................................................................................... 29 3.3 - Srialisation..................................................................................................................................................29 3.4 - Relations avec le contexte.......................................................................................................................... 30 3.5 - Accs concurrentiel..................................................................................................................................... 31 3.6 - Transactions.................................................................................................................................................32 Conclusion..................................................................................................................................................................34 Remerciements.......................................................................................................................................................... 35
-2Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Avant-Propos
Qui ne s'est jamais arrach les cheveux pour rcuprer ou mettre jour des donnes stockes dans une base de donnes relationnelle comme SQL Serveur, Oracle ou MySQL ? Ecrire des lignes de SQL directement dans votre code C# ou VB.Net peut s'avrer dlicat et long dbuguer. Avec l'arrive de LinQ To SQL, Microsoft propose une solution lgante pour requter une base de donnes sans crire une seule ligne de SQL. Les requtes sont crites avec des mots-cls du langage C# ou VB.Net et des objets, ceci permet une vrification de la syntaxe la compilation. Alors que LinQ to SQL propose seulement un mapping "Une classe = Une table", la nouvelle solution de mapping objet-relationnel de Microsoft, nomme Entity Framework propose une approche bien plus avance. Entity Framework est un outil permettant de crer une couche d'accs aux donnes (DAL pour Data Access Layer) lie une base de donnes relationnelle. Il propose la cration d'un schma conceptuel compos d'entits qui permettent la manipulation d'une source de donnes, sans crire une seule ligne de SQL, grce LinQ To Entities. Compar d'autres solutions de mapping objet-relationnel (ORM), Entity Framework assure l'indpendance du schma conceptuel (entits ou objets) du schma logique de la base de donnes, c'est--dire des tables. Ainsi, le code produit et le modle conceptuel ne sont pas coupls une base de donnes spcifique. Cet article prsente Entity Framework travers les 3 aspects suivants : Les concepts d'Entity Framework Dfinition d'un modle EDM Utilisation des entits et du contexte
La 1re partie est une introduction thorique l'outil. Alors que les 2 dernires concernent son utilisation par un exemple concret.
-3Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Prrequis logiciels
Pour utiliser Entity Framework et l'assistant de modle EDM intgr Visual Studio 2008, vous avez besoin des prrequis suivants : Visual Studio 2008 (dition standard, professionnelle ou team) Visual Studio 2008 Service Pack 1 (contient l'assistant de modle EDM) SQL Serveur 2005 (toutes ditions confondues)
Le code sources de l'article (miroir http) contient 2 scripts SQL installer qui se trouvent dans le dossier SQL, la racine de l'archive : "DB-helloentityfx.sql" cre la base de donnes "helloentityfx", ses tables, vues et procdures stockes. "(FR)Data-helloentityfx.sql" (pour la version franaise de SQL Serveur 2005) et "(EN)Datahelloentityfx.sql" (pour la version anglaise de SQL Serveur 2005) insrent les donnes de test dans la base "helloentityfx".
L'archive de l'article contient aussi un projet Visual Studio 2008 reprenant l'ensemble du code C# ainsi que le modle EDM de l'article. L'article fait rfrence Visual Studio 2008 dans sa version anglaise. Toutes les dmonstrations et explications sont aussi valables pour la version franaise du logiciel.
-4Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Cette architecture particulire permet une totale indpendance entre les objets utiliss dans la couche d'accs aux donnes et les lments (tables, vues, procdures stockes) de la base de donnes. Il est ainsi possible de modifier le schma logique sans que cela n'ait d'impact sur la dfinition des objets et inversement. Il est juste ncessaire de mettre jour le schma de liaison MSL. Lors du traitement d'oprations CRUD (cration, lecture, mise jour et suppression), le framework utilise le modle EDM pour construire les requtes SQL. A partir d'une entit dfinie dans le fichier CSDL, il est possible de retrouver la ou les tables associes dcrites dans le schma logique grce au schma de liaison qui associe les entits aux tables. Il existe 2 outils permettant de gnrer un modle EDM : "EdmGen.exe" et l'assistant de modle EDM intgr Visual Studio. Le premier est contenu dans framework .Net 3.5. Celui-ci fonctionne en ligne de commande. Il permet entre autre de : Gnrer les fichiers CSDL, MSL, SSDL partir d'une base de donnes. Gnrer les classes d'entit et la classe de contexte partir du fichier CSDL. Valider le modle EDM partir de la base de donnes. documentation officielle.
Visual Studio 2008 SP1 intgre aussi un assistant permettant de gnrer un modle EDM, et ce de manire graphique. Il ressemble assez l'assistant LinQ to SQL pour les connaisseurs et il offre un confort d'utilisation bien meilleur que l'outil en ligne de commande, au dtriment d'un certain manque de fonctionnalits.
-5Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Par exemple, il n'est pas possible de dfinir de type complexe avec l'assistant, alors que "EdmGen.exe" le permet. Rassurez-vous, vous pouvez commencer utiliser l'assistant (gain de temps vident) et utiliser par la suite l'outil en ligne de commande. Nanmoins, il s'avre regrettable d'avoir recours ce genre de manipulation. La prochaine version de l'assistant devrait corriger cela, et bien d'autres points. L'article se base sur l'assistant de modle EDM car il couvre la majorit des besoins utilisateurs. L'assistant de Visual Studio 2008 concatne les 3 schmas (CSDL, MSL et SSDL) en un seul fichier de type "edmx". Ce fichier contient aussi des informations relatives l'agencement graphique des entits dans le modle. Pour utiliser par la suite "EdmGen.exe", il faudra extraire manuellement les lements XML des 3 schmas et les insrer dans 3 fichiers distincts.
Cet article se focalisera quasi exclusivement sur LinQ To Entities. Peut-on utiliser des classes mtier n'hritant pas de "EntityObject" ? La rponse est oui ! Au minimum, il est ncessaire que vos classes hritent des interfaces suivantes : IEntityWithChangeTracker : Active le suivi des modifications (obligatoire). IEntityWithKey. Facultatif : Expose une cl d'entit (obligatoire). IEntityWithRelationships : Obligatoire pour les entits prsentant des associations (facultatif). documentation officielle.
Implmenter ces 3 interfaces sous-entend que vos classes mtiers doivent tre modifies pour utiliser la persistance avec Entity Framework. En d'autres termes, le principe de faible couplage / forte cohrence n'est pas respect puisque les classes mtiers contiennent la fois de la logique mtier et de la logique de persistance. Un design POCO signifie que les classes mtiers ne contiennent aucune logique de persistance. Finalement dans certains scnarios, il n'est pas possible de modifier ses classes mtiers.
-6Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
On peut en tirer la conclusion suivante : Entity Framework ne permet pas d'utiliser des classes POCO (Plain Old Code/ csharp Object). D'autres outils le permettent comme NHibernate avec l'utilisation d'objets proxy. Danny Simmons, dveloppeur de l'quipe d'Entity Framework s'explique les prochaines versions de l'outil. ce sujet. Souhaitons que ce manque soit combl dans
Cependant, sachez qu'il est possible de contourner ce manque avec l'utilisation de la programmation oriente aspect. Sans rentrer dans les dtails, PostSharp permet d'injecter du code lors d'une 2me phase de compilation et donc Un projet a d'ailleurs t ralis ce sujet. son blog. d'implmenter les 3 interfaces ncessaires sur les classes POCO. Vous trouverez plus d'information sur
La requte LinQ utilise une proprit spcifique, "Publication", de la classe "Modele" renvoyant un objet de type "ObjectQuery<Publication>". C'est grce a cet objet que l'on peut requter la source de donnes. Ici la requte rcupre l'ensemble des publications insres dans la table "Publication" de la base de donnes. Le rsultat est de type "IQueryable<Publication>", qui hrite de la classe "IEnumerable<T>". Ceci permet de diffrer l'excution de la requte, grce son itrateur, qui n'est excute qu' l'appel de la mthode "ToList" transformant en une liste de type "List<Publication>" le rsultat de la requte.
-7Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Ce dernier fournisseur de donnes est spcifique la base de donnes utilise. Le fournisseur utilis est dfini par la chaine de connexion utilise par l'objet "EntityConnection", qui a la responsabilit d'ouvrir la connexion de la source de donnes. Voici un exemple de chaine de connexion, dfinie par l'assistant de Visual Studio 2008 :
metadata=res://*/modele.csdl|res://*/modele.ssdl|res://*/modele.msl; provider=System.Data.SqlClient;provider connection string="Data Source=TLS-LOG-PO-PMO\SQLEXPRESS; Initial Catalog=helloentityfx;Integrated Security=True;MultipleActiveResultSets=True"
La 1re partie concerne les mtadonnes de la connexion. On y voit la rfrence aux 3 schmas du modle EDM, et du fournisseur de donnes utilis pour la base de donnes. Ici, c'est la classe "System.Data.SqlClient" qui permet de communiquer avec une base de type SQL Serveur 2000/2005/2008. L'assistant de modle EDM gnre les 3 schmas du modle EDM et les insre en tant que ressource dans l'assembly du projet. C'est pour cela que la chaine de connexion fait rfrence des fichiers ressources. Il est donc possible de spcifier un autre fournisseur de donnes pour utiliser, par exemple, une base Oracle, MySQL ou PostgreSQL. Voici une liste non exhaustive des fournisseurs de donnes compatibles avec Entity Framework : Oracle : http://devart.com/dotconnect/oracle/ (payant) MySQL : http://devart.com/dotconnect/mysql/ (payant) PostgreSQL : http://pgfoundry.org/frs/shownotes.php?release_id=1230 (gratuit) SQLite : http://sqlite.phxsoftware.com/, http://devart.com/dotconnect/sqlite/ (gratuit) projet sur Codeplex fournit le code
-8Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
La fentre principale. Elle affiche les lments du modle EDM. Les entits sont reprsentes par une forme rectangulaire grise contenant les proprits scalaires et les proprits de navigation. Il est possible de rajouter des proprits scalaires partir du menu contextuel ("Add > Scalar Property"). Les associations entre entits sont reprsentes avec leurs cardinalits par un trait pointill avec des losanges chaque extrmit. Les relations d'hritage entre entits sont reprsentes par un trait plein et une flche dsignant l'entit mre. L'explorateur de modle (en haut droite) est un arbre o sont rpertoris les lments du schma conceptuel et ceux du schma logique. Le menu contextuel (Update model from database) permet de mettre jour le modle EDM partir de la base de donnes. Par exemple, si vous ajoutez une table, la mise jour rajoute l'lment correspondant dans le schma logique, ajoute une entit au schma conceptuel et prdfinit le mapping entre les deux. La fentre de proprits (au milieu droite) permet de dfinir les proprits du modle, des entits, des proprits scalaires, de navigation et des associations slectionnes. Les dtails de mapping des entits (en bas). En slectionnant une entit, le mapping, entit <-> base de donnes, est affich. Il est possible de slectionner la ou les tables en relation avec l'entit. Pour chaque table, vous pouvez dfinir la relation entre chaque colonne de la table et les proprits de l'entit. L'diteur de mapping permet aussi de spcifier les procdures stockes utilises pour les oprations de cration, de mise jour, et de suppression d'une entit. Sachez qu'il n'est pas possible de dfinir qu'une procdure ou 2 sur les 3. Soit vous les spcifiez toutes, soit aucune.
La partie suivante de l'article montre comment utiliser l'diteur afin de crer un modle EDM pour la base de donnes "helloentityfx" (voir prrequis).
-9Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Le but de cette partie est de dfinir un modle EDM et un schma conceptuel permettant de mettre jour et de requter l'ensemble de ces tables par l'intermdiaire des entits ainsi que du contexte. Pour commencer, crez un projet de type "Console Application", nomm "HelloEntityFramework":
- 10 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Ajoutez ensuite un nouvel item de type "ADO.Net Entity Data Model" au projet nomm "modele.edmx" :
Sur la 1re fentre de l'assistant, slectionnez la 1re icne, nomme "Generate from database". En faisant cela, les entits du schma conceptuel vont tre gnres partir de la base de donnes "helloentityfx". Cette opration va aussi crer le schma logique SSDL (bases de donnes) ainsi que le mapping entre les entits et les lments de la base de donnes (schma MSL). Ajoutez ensuite une nouvelle connexion de type "Microsoft SQL Server" :
- 11 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Dans la fentre "Connection Properties", slectionnez l'instance du serveur SQL Server hbergeant la base de donnes "helloentityfx" dans le champ "Server name" et choisissez la base de donnes "helloentityfx" dans la liste d'en-dessous. Validez ensuite la connexion aux donnes. Il ne reste plus qu' choisir les objets qui seront imports dans le modle. Cochez "Tables", "Views" et "Stored Procedure", dfinissez le champ "Model Namespace" "HelloEntityFramework" et cliquez sur "Finish" pour valider cette dernire tape.
- 12 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Aprs validation, Visual Studio est appelle le custom tool "EntityModelCodeGenerator" transformant les donnes XML du fichier "modele.edmx" en un ensemble de classes drivant de "System.Data.Objects.DataClasses.EntityObject" pour les entits et de "System.Data.Objects.ObjectContext" pour l'objet contexte. La classe "contexte" est appele par dfaut "helloentityfxEntities1". Ouvrez le modle avec l'diteur de modle EDM et dans les proprits du modle, dfinissez la valeur "Entity Container Name" "Modele". Cette manipulation a pour effet de modifier le nom de la classe de contexte.
2.1 - L'hritage
Il existe 2 types d'hritage dans Entity Framework : Une table par type d'entit : Pour chaque entit dans la hirarchie d'hritage, il existe une table dans la base de donnes. Une seule table pour toutes les entits : Quelque soit le nombre d'entits contenues dans la hirarchie d'hritage, il n'existe qu'une seule table en base de donnes.
- 13 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Nous allons voir comment implmenter ces 2 types d'hritage dans notre modle.
Du ct des entits, il y en a aussi 4 bien distinctes et n'ayant aucune relation d'hritage entre elles. Chacune correspond une des 4 tables cites prcdemment. Une bonne modlisation voudrait que les entits "EditeurBD", "EditeurPsychologie" et "EditeurInformatique" hritent de l'entit "Editeur" :
Pour cela, il suffit de rpter la manipulation suivante sur les 3 entits spcialiser : Supprimez la proprit faisant office de cl d'entit (proprit Id dans notre cas) dans l'entit fille. Faites un click n'importe o dans l'diteur de modle EDM et slectionnez "Add > Inheritance ...". Dans la liste droulante "Select a base type", choisissez "Editeur" et dans l'entit driver, slectionnez l'une des 3 entits cites prcdemment. Validez le formulaire pour finir.
- 14 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Affichez les proprits de mapping de l'entit drive, et dfinissez pour la colonne Id la proprit "Id:Int32".
Pour chaque entit, une proprit de type "ObjectQuery<TypeEntit>", aussi appele "Entity Set", est cre dans l'objet contexte. Cependant, pour les entits drives ce n'est pas le cas. Pour effectuer une requte de type SELECT concernant uniquement une entit spcifique, une bonne solution est d'utiliser la mthode "OfType<T>", voici un exemple :
using (Modele bdd = new Modele()) { var requete = from editeurInfo in bdd.Editeur.OfType<EditeurInformatique>() select editeurInfo; }
Cette requte rcupre l'ensemble des diteurs informatiques stocks dans les tables "Editeur" et "EditeurInformatique". Pour l'insertion d'une nouvelle entit drive en base, il suffit d'appeler une mthode de l'objet contexte nomme ainsi : AddTo[TypeDeBase].
- 15 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
using (Modele bdd = new Modele()) { EditeurInformatique OReilly = new EditeurInformatique() { Nom = "OReilly", NombreLivresInfoEdites = 1800 }; bdd.AddToEditeur(OReilly); bdd.SaveChanges();
Du ct de la base de donnes, une nouvelle ligne est insre dans la table "Editeur" ainsi que dans la table "EditeurInformatique". Les 2 lments ont la mme valeur de cl primaire.
Au niveau du modle, il existe une entit "Publication" mappe la table du mme nom. Le but est d'avoir 2 types de publication : les livres et les articles. Ces 2 entits doivent hriter de l'entit Publication. L'entit "Article" a la particularit d'avoir une proprit "Url", que n'a pas l'entit "Livre". Dernire prcision, l'entit "Publication" n'a pas vraiment de sens en soi, le mieux est de la dfinir comme abstraite. Pour commencer, supprimez la proprit "Url" et "Type" de l'entit "Publication". La 1re sera dfinie uniquement dans l'entit "Article". Quand la seconde, elle sert de condition pour l'hritage spcifi dans le schma conceptuel. Dans les proprits de "Publication", dfinissez l'entit comme abstraite (Abstract = True). Afin de crer l'entit 'Livre", faites un click droit quelque part dans l'diteur de modle EDM et choisissez "Add > Entity ". Dfinissez les valeurs comme ci-dessous :
- 16 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Il faut ensuite dfinir les proprits de mapping. Slectionnez la table "Publication" dans le champ "Add a Table or View". Ajoutez une condition sur la colonne "Type", laissez l'oprateur gal et dfinissez la valeur 0.
Crez ensuite l'entit "Article" de la mme manire que "Livre". Ajoutez cependant une proprit l'entit ("Add > Scalar Property") s'appellant "Url" et de type "String". Dans les proprits de mapping, choisissez la table "Publication" et dfinissez une condition sur la colonne "Type" de valeur gale 1. Au niveau de la colonne "Url", choisissez la proprit Url de type "String".
- 17 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Elles proposent aussi des avantages convaincants concernant la scurit, les performances et l'encapsulation. Ce dernier point souligne le fait qu'une procdure stocke peut renfermer une logique complexe concernant, par exemple,
- 18 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
de la mise jour de donnes. Cela vite chaque programme diffrent de devoir reprogrammer cette logique. Un simple appel la procdure stocke suffit.
Dans l'encadr "Return Type", slectionnez "Entities" et dans la liste, slectionnez "Auteur". La procdure stocke "GetAuteurs" renvoie l'ensemble des auteurs contenus dans la table "Auteur". Validez en appuyant sur "OK". Cette opration rajoute une fonction nomme l'objet contexte "Modele". Pour l'excuter, il suffit d'appeler la mthode C# nomme "GetAuteurs" de la classe "Modele". Voici un exemple :
public static void AppelProcdureStocke() { using (Modele bdd = new Modele()) { var requete = bdd.GetAuteurs(); requete.ToList().ForEach(a => Console.WriteLine("Auteur : ID = {0}, Nom = {1}, Prenom = {2}", a.Id, a.Nom, a.Prenom)); } }
- 19 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
"CreerClient" prend en entre le nom, le prnom, le pays, la rue, le code postal, le tlphone ainsi que la ville du client et renvoie l'identifiant gnr par la base de donnes. "MAJClient" prend en entre l'id, le nom, le prnom, le pays, la rue, le code postal, le tlphone, la ville et met jour le client ayant le mme id que celui pass en paramtre. "SupprimerClient" prend en entre l'id d'un client et supprime l'entre correspondante dans la table.
D'une faon gnrale, toutes les procdures stockes servant de substitution des requtes de mise jour, suppression ou cration doivent avoir la mme forme et la mme logique que les 3 prcdentes. Pour plus d'informations sur ces procdures stockes, je vous invite regarder le script de cration de la base de donnes "DB-helloentityfx.sql" fourni dans l'archive de l'article. Pour utiliser ces procdures stockes, ouvrez le fichier "modele.edmx" avec l'diteur de modle EDM. Cliquez droit sur l'entit "Client" et slectionnez "Stored Procedure Mapping". Cet diteur apparait :
Cliquez sur "<Select Insert Function>" et choisissez la procdure stocke "CreerClient". L'diteur se charge ensuite de relier chaque proprit de l'entit aux arguments de la procdure stocke. Il ne reste plus qu' dfinir le nom de la variable renvoye par la procdure stocke contenant le nouvel identifiant et de le relier la proprit "Id" de l'entit. Pour cela, entrez "Id" dans la case "<Add Result Binding>" juste en dessous du dossier "Result Column Bindings". Effectuez la mme manipulation pour la procdure stocke utilise pour la mise jour et la suppression. A ceci prs qu'il n'est pas ncessaire de dfinir de valeur de retour pour la fonction de mise jour. Voici le rsultat en image :
- 20 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Il n'est pas possible de dfinir une seule voire 2 procdures sur les 3. Soit vous n'en dfinissez aucune, soit vous les dfinissez toutes.
- 21 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Supprimez la table "CoordonneesAuteur" et ajoutez les proprits "Rue", "Ville", "CodePostal", "TelephoneFixe" et "TelephoneMobile" l'entit "Auteur", comme ceci :
Chaque proprit insre doit tre de type "String". Ensuite, dans les dtails du mapping, il faut ajouter une relation la table "CoordonneesAuteur". Normalement, l'diteur assigne automatiquement tous les champs de la table aux proprits ayant le mme nom dans l'entit "Auteur", sauf pour "IdAuteur" qu'il faut spcifier avec la proprit "Id" (mappe sur le champ Id de la table "Auteur").
- 22 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Sauvegardez pour dclencher le custom tool qui est charg de gnrer le code, les entits et l'objet contexte. L'entit "Auteur" contient maintenant toutes les proprits correspondantes aux champs des 2 tables "Auteur" et "CoordonneesAuteur". Le fait de renseigner un des 5 champs ajouts l'entit "Auteur" cre une nouvelle entre dans la table "CoordonneesAuteur".
Ces champs pourraient faire rfrence une nouvelle entit s'appelant "Adresse" et contenant 5 proprits correspondant ces champs. La classe client perdrait donc ces 5 proprits mais aurait une proprit nomme "Adresse" de type "Adresse". Cette entit a la particularit de ne contenir aucune cl d'entit et donc de n'tre mappe aucune cl primaire. L'entit dcrite est simplement utilise par une autre entit qui elle, contient bien une cl d'entit valide. Dans Entity Framework, cela s'appelle un type complexe. Avec l'outil en ligne de commande "EdmGen.exe" se trouvant dans le dossier suivant "C:\Windows\Microsoft.NET \Framework\v3.5", il est tout fait possible de dfinir un type complexe. Cependant, ce n'est pas possible avec l'diteur de modle fourni dans Visual Studio, en tout cas, pas dans sa 1re version.
- 23 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
- 24 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
LinQ To Entities permet d'crire des requtes syntaxiquement proches du SQL, et cela directement en C# ou VB.Net. L'avantage majeur vient du fait que les requtes produites sont vrifies la compilation et non plus l'excution. Comme pour chaque implmentation de LinQ, chaque requte est transforme en un arbre d'expression (cr par l'objet ObjectContext) qui est au final traduit en SQL par le fournisseur de donnes final. Le rsultat d'une requte LinQ to Entities est de type "IQueryable<T>" o T est le type spcifi dans la clause SELECT de la requte. Voici donc un exemple de requte LinQ to Entities :
var requete = from publication in bdd.Publication select publication;
Le rsultat est de type "IQueryable<Publication>". Il est possible d'itrer sur les rsultats avec une simple boucle "foreach". Vu que "IQueryable<T>" implmente un numrateur, sachez que la requte vers la source de donnes est uniquement excute lors du parcours des rsultats. Pour plus d'information, veuillez vous rfrencer la documentation officielle de l'objet "IQueryable<Publication>".
Linq to Entities supporte un ensemble de mthodes pour requter la source de donnes dont voici une liste non exhaustive ( url de la liste complte) :
Select, SelectMany Where GroupJoin, Join All, Any Distinct Except Intersect Union OrderBy, OrderByDescending, ThenBy, ThenByDescending GroupBy Average Count, LongCount Max, Min, Sum
- 25 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Voici l'exemple d'une requte slectionnant seulement les publications qui contiennent le mot "C#" dans leur titre :
var requete = from publication in bdd.Publication where publication.Titre.Contains("C#") select publication;
Pour plus d'informations sur les requtes LinQ, je vous invite lire l'
Il est aussi possible de requter la source de donnes grce Entity SQL. C'est un langage hritant du vocabulaire et de la grammaire de type SQL. Ce langage permet de rcuprer des produits scalaires, des ensembles de rsultat et des graphes d'objets. Pour une description du langage, veuillez vous rfrer la Voici l'exemple d'une requte rcuprant toutes les publications stockes en base :
string chaineRequete = "SELECT VALUE p FROM Publication AS p"; // Dfinition de la requte de type ObjectQuery<Publication> ObjectQuery<Publication> requete = new ObjectQuery<Publication>(chaineRequete, bdd, MergeOption.NoTracking);
documentation officielle.
En dernier choix, vous pouvez utiliser les mthodes du gnrateur de requtes de la classe "ObjectQuery<T>". En voici un exemple :
// Dfinition de la requte de type ObjectQuery<Publication> var requete = bdd.Publication.SelectValue<Publication>("it");
La suite de l'article fera uniquement rfrence LinQ to Entities, mais toutes les requtes faites sur le modle peuvent tre ralises avec Entity SQL ou grce aux mthodes du gnrateur de requtes de la classe "ObjectQuery<T>". Chaque entit en relation avec une autre possde une collection d'entits connexes. Cependant, celle-ci n'est pas initialise par dfaut. Pour naviguer vers ces entits, il est ncessaire de les charger explicitement : soit en utilisant la mthode "Include" de "ObjectQuery<T>", soit en utilisant la mthode "Load" appartenant la classe "EntityReference<T>" ou "EntityCollection<T>".
L'exemple suivant utilise la mthode "Include" pour rcuprer explicitement, lors de la requte, l'diteur et les auteurs associs aux publications :
using (Modele bdd = new Modele()) { var requete = from publication in bdd.Publication.Include("Auteur").Include("Editeur") select publication; requete.ToList().ForEach((Publication p) => { Console.WriteLine("Publication : ID = {0} | Titre = {1}", p.Id, p.Titre); Console.WriteLine(" Editeur : ID = {0} | Nom = {1}", p.Editeur.Id, p.Editeur.Nom);
p.Auteur.ToList().ForEach(a => Console.WriteLine(" Auteur : ID = {0} | Nom = {1} {2}",a.Id,a.Prenom,a.Nom)); }); - 26 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Voici un autre exemple avec l'utilisation de la mthode "Load". Remarquez que chaque collection ou chaque rfrence lie une entit possde une proprit "IsLoaded" permettant de savoir si la ou les entits connexes sont charges.
using (Modele bdd = new Modele()) { var requete = from publication in bdd.Publication select publication; requete.ToList().ForEach((Publication p) => { if (!p.EditeurReference.IsLoaded) p.EditeurReference.Load(); Console.WriteLine(" if (!p.Auteur.IsLoaded) p.Auteur.Load(); a.Id, }); p.Auteur.ToList().ForEach(a => Console.WriteLine(" a.Prenom, a.Nom)); Auteur : ID = {0} | Nom = {1} {2}", Editeur : ID = {0} | Nom = {1}", p.Editeur.Id, p.Editeur.Nom);
Pour supprimer une entit, il suffit d'indiquer au contexte via la mthode "DeleteObject" l'entit souhaite, et de valider l'action avec la mthode "SaveChanges" :
using (Modele bdd = new Modele()) { var requete = from c in bdd.Client where c.Nom == "Oliver" select c; var client = requete.FirstOrDefault(); if (client != null) { bdd.DeleteObject(client); bdd.SaveChanges(); }
- 27 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Concernant la mise jour d'entits, modifiez simplement les proprits souhaites et validez avec la mthode "SaveChanges". Grce l'objet de type "ObjectStateManager", le contexte sait quelles proprits doivent tre mises jour lors de la mise jour de la source de donnes, la condition que l'entit soit bien attache au contexte.
using (Modele bdd = new Modele()) { Client client = (from c in bdd.Client where c.Nom == "Oliver" select c).FirstOrDefault(); if (client != null) { client.Ville = "Bruxelles"; client.Pays = "Belgique"; bdd.SaveChanges(); } }
Mettre jour une relation entre 2 entits est tout aussi simple, il suffit d'assigner la proprit adquate l'entit connexe, tout du moins pour une relation * -> 1. Pour une relation de type * -> *, il faut ajouter la ou les entits connexes avec la mthode "Add" de la proprit faisant rfrence la relation.
using (Modele bdd = new Modele()) { Emprunt emprunt = new Emprunt() { Client = bdd.Client.First(), DateDebut = DateTime.Now, Exemplaire = bdd.Exemplaire.First() }; bdd.AddToEmprunt(emprunt); bdd.SaveChanges(); }
- 28 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Introduction Entity Framework par Paul Musso (Blog) public override string ToString() { StringBuilder strBuilder = new StringBuilder(); strBuilder.Append("Client : "); strBuilder.Append("Nom = "); strBuilder.Append(Nom); strBuilder.Append("Prenom = "); strBuilder.Append(Prenom); return strBuilder.ToString(); }
Le gnrateur de classes gnre pour chaque proprit d'une entit 2 appels synchrones des mthodes partielles. Celle contenant "Changing" est appele avant l'affectation de la valeur la proprit. Celle contenant "Changed" est appele aprs l'affectation de la valeur la proprit. Ces 2 types de mthodes offrent une bonne opportunit d'ajouter de la logique mtier. Il est noter que si une mthode partielle n'est pas dfinie, celle-ci ne figure pas dans le code MSIL (langage intermdiaire gnr par le compilateur C#). On peut penser une sorte d'optimisation par rapport aux vnements ordinaires.
La mthode "Modele_SavingChanges" reoit en paramtre le contexte sous la forme d'un objet de type "object". Celle prsente ci-dessus affiche le type des entits ajoutes la base de donnes. C'est aussi un bon emplacement pour y dfinir des rgles ou des contraintes qui doivent tre respectes.
3.3 - Srialisation
Les classes drivant de la classe "Entity" peuvent tre srialises de 3 manires diffrentes:
- 29 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
En binaire avec l'aide de la classe "BinaryFormatter". Vous trouverez ici un exemple sur MSDN En XML l'aide de la classe "XmlSerializer" Par WCF puisque chaque classe "Entity" implmente l'attribut "DataContract" et chaque membre l'attribut "DataMember".
public static void DeserialisationXML() { Console.WriteLine("Dsrialisation d'un client contenu dans un fichier XML"); XmlSerializer serialiseur = new XmlSerializer(typeof(Client)); TextReader textReader = new StreamReader("client.xml"); Client client = (Client)serialiseur.Deserialize(textReader); textReader.Close(); } Console.WriteLine(client.ToString());
La srialisation WCF ainsi que binaire srialise toutes les entits charges et rattaches l'entit que l'on veut srialiser. Par contre, la srialisation XML ne supporte pas cette fonctionnalit. Pour contourner ce comportement, il est ncessaire de rajouter de la logique permettant de rattacher les entits en relation avec l'entit voulue, et bien srialiser une une chaque entit.
Il est possible d'attacher une entit qui ne l'est pas. Pour cela, la mthode "Attach" de l'objet "ObjectContext" prend en paramtre l'entit attacher. Cependant, celle-ci est attache avec son tat dfinit "Unchanged". Cela veut dire que toute modification applique avant l'appel la mthode "Attach" est perdue. De mme, l'entit doit avoir une cl ("EntityKey") valide. Dans le cas contraire, la mthode "AttachTo" est ncessaire.
- 30 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
public void AttacherEntit(Client pClient) { using (Modele bdd = new Modele()) { // Attacher un objet au contexte if (pClient != null) bdd.Attach(pClient); } }
Le fait d'attacher une entit, attache aussi les entits qu'elle peut avoir en relation. Dans le cas o une entit dtache a subi des modifications qui doivent tre sauvegardes en base, vous pouvez utiliser la mthode "ApplyPropertyChanges". Celle-ci prend en paramtre le nom de l'ensemble d'entits ("Entity Set") et de l'entit contenant les modifications sauvegarder.
public void MiseAJourEntit(Client pClient) { using (Modele bdd = new Modele()) { // Extraction et cration de la cl de l'entit EntityKey key = bdd.CreateEntityKey("Client", pClient); // Essaie de rcuprer l'entit originale partir de sa cl object clientOriginal; if (bdd.TryGetObjectByKey(key, out clientOriginal)) { // Applique les modifications de l'entit dtach comportant des modifications bdd.ApplyPropertyChanges(key.EntitySetName, pClient); } } bdd.SaveChanges();
Cependant, cet accs concurrentiel n'est pas activ par dfaut. Tout d'abord, l'accs concurrentiel concerne une proprit d'une entit. Si vous souhaitez l'activer sur toutes les entits et sur toutes leurs proprits, il faut rpter la manipulation suivante autant de fois que ncessaire. Ouvrez votre modle avec le designer de modle EDM, slectionnez une entit quelconque (Client par exemple), slectionnez une proprit et dans les proprits de celle-ci se trouve la valeur "Concurrency Mode" dfinie "None" (Prnom pour l'exemple ci-dessous). Dfinissez l "Fixed" pour activer la concurrence. Une fois active, la logique de mise jour ou de suppression peut gnrer des exceptions de type "OptimisticConcurrencyException", lorsque les donnes du cache d'Entity Framework et de la base de donnes ne sont plus les mmes au moment de l'appel la mthode "SaveChanges" du contexte. Ce cas de figure arrive frquemment lorsque plusieurs clients consomment et mettent jour la mme base de donnes. Comme cit plus haut, soit nous utilisons comme rfrentiel les donnes locales ou bien celles de la base de donnes. Ceci est dcid grce la mthode "Refresh" de l'objet contexte, qui prend en paramtre une valeur de l'numration RefreshMode
- 31 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
("ClientWins" ou "StoreWins") et l'entit rafrachir. Voici un exemple que vous pouvez reproduire avec la base "helloentityfx":
public static void RefreshEntit() { Console.WriteLine("Rcuprer une entit en cas de conflit (Accs concurrentiel)"); using (Modele bdd = new Modele()) { Client client = null; try { client = (from c in bdd.Client where c.Nom == "Oliver" select c).FirstOrDefault(); simulerAccesConcurrentiel(bdd.Connection.DataSource); client.Prenom = "Fabrice"; bdd.SaveChanges(); Console.WriteLine("Aucun conflit"); } catch (OptimisticConcurrencyException exp) { Console.WriteLine("Conflit dtect. Message : {0}", exp.Message); bdd.Refresh(RefreshMode.StoreWins, client); bdd.SaveChanges();
private static void simulerAccesConcurrentiel(string pDataSource) { using (SqlConnection connexion = new SqlConnection("Data Source=" + pDataSource + ";Initial Catalog=helloentityfx;Integrated Security=SSPI;")) { connexion.Open(); string strCmd = "UPDATE Client SET Prenom = 'Johnny' WHERE Nom = 'Oliver'"; SqlCommand command = new SqlCommand(strCmd,connexion); command.ExecuteNonQuery(); } connexion.Close();
La mthode "simulerAccesConcurrentiel" utilise une connexion ADO.Net classique pour mettre jour l'entre de la table "Client" correspondant l'entit prcdemment rcupre, simulant un accs concurrentiel. A l'appel de la mthode "SaveChanges" dans le block "try", une exception de type "OptimisticConcurrencyException" est rcupre. Elle est ensuite affiche dans le block "catch", o nous dcidons de mettre jour l'entit en utilisant comme rfrentiel la base de donnes :
... bdd.Refresh(RefreshMode.StoreWins, client); ...
3.6 - Transactions
Entity Framework supporte les transactions de manire automatique, tout du moins en ce qui concerne la source de donnes.
- 32 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Les transactions sont utiles lorsqu'il est ncessaire d'excuter plusieurs oprations comme si ce n'tait qu'une seule. Si une opration de la transaction choue en gnrant une exception, toutes les oprations prcdentes sont annules. D'une faon gnrale, une transaction respecte les 4 contraintes suivantes (ACID) : Atomicit : Une transaction doit s'excuter totalement ou pas du tout. Cohrence : La cohrence des donnes doit tre absolument respecte mme en cas d'erreur. Il doit tre possible d'annuler les oprations en cas d'erreur. Isolation : La transaction doit s'effectuer dans un mode isol o elle seule peut voir les modifications en cours. Durabilit : Une fois la transaction termine, le systme est dans un tat stable, quelque soit ce qui s'est pass durant la transaction.
Entity Framework cre une transaction lors de l'appel la mthode "SaveChanges" du contexte. Ceci permet de maintenir un tat cohrent entre la source de donnes et le contexte. Si vous souhaitez ajouter d'autres oprations concernant des systmes externes, comme un annuaire, une autre base de donnes ou un envoi de mail, il est ncessaire de dclarer explicitement une transaction. Dans ce cas, Entity Framework utilisera automatiquement celle-ci. Une transaction distribue a aussi besoin d'un coordinateur de transaction distribue (DTC) et tous les systmes externes appels doivent tre compatibles. Pour pouvoir relancer une transaction ayant chou, il faut appeler la mthode "SaveChanges" avec le paramtre "acceptChangesDuringSave" gal "false", et ne pas oublier l'appel la mthode "AcceptAllChanges" une fois la transaction valide. Voici un exemple avec le modle de l'article :
int nbEssai = 3; bool transactionExecutee = false; using (Modele bdd = new Modele()) { while (nbEssai > 0 && !transactionExecutee) { try { Client client = new Client() { Nom = "Prenom", Prenom = "Paul" }; bdd.AddToClient(client); bdd.SaveChanges(false); transactionExecutee = true;
} if ( transactionExecutee ) bdd.AcceptAllChanges();
- 33 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Conclusion
Entity Framework reprsente la solution tant attendue de mapping objet-relationnel de Microsoft. Elle constitue une bonne alternative des outils comme NHibernate, grce son architecture ingnieuse du modle EDM et des entits. L'diteur de modle EDM de Visual Studio 2008 permet aussi de faire gagner un temps prcieux dans la dfinition des entits et de leur mapping. L'quipe d'ADO .Net prpare en ce moment une version 2 corrigeant certaines lacunes concernant l'utilisation des classes POCO et du designer.
- 34 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
Remerciements
Je tiens remercier Jrme Lambert, pvialatte et Louis-Guillaume Morand pour leurs conseils et encouragements ainsi que Maximilian pour la correction orthographique.
- 35 Les sources prsentes sur cette pages sont libre de droits, et vous pouvez les utiliser votre convenance. Par contre cette page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright - Paul Musso. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.