Mapping objet relationnelMitsuru FURUTA – Microsoft Francemitsufu@microsoft.comhttp://blogs.microsoft.fr/mitsufu
Objectifs de la présentationC’est une présentation technique !Appréhender les conceptsComprendre les problématiquesEtre capable d’évaluer un produitMettre en œuvre les principes fondamentaux sous forme de courtes démosPas de présentation de produitPas de parti prisPas de LINQ…C’est une présentation technique !
Mapping objet relationnelIntroductionModélisationArchitectureFonctionnalités attendues de la couche objetProductivitéMySolution: DSMap, un DataSet objet…La pause ? Quelle pause ?
IntroductionEnjeux et problématiquesDatabase != objectsArchitecture multi-couche: DAL, business, présentationEst-il possible d’automatiser la DAL ?Amener la persistance aux objets métiersModélisationRecherche du modèle uniqueRequêtageTuer le SQLImplémentationsOutils ou framework ?Modèle intrusif ou pasSolutions souvent techniquesGénération de code: templates dynamiques, CodeDomAbstraction: proxy dynamique, tissage
IntroductionIdéal ?Le pur mapping O/R ne requiert aucun prérequis ni de la part de la base ni de la part de la couche objet. Il assure le lien entre les deux quelques soient les modèles.La solution assure en général l’accès à la base et la création automatiques des objets (classFactory).Les solutions sont en général riches mais coûteuses en ressources et en performances.Data baseObjectsMapping O/R
IntroductionRéalitéDe nombreuses solutions ont le parti pris de se baser soit sur la base soit sur les objets. Les informations de mapping accompagnent alors le modèle choisi et servent à générer le modèle opposée (la base ou les objets)Ces modèles s’utilisent dans la phase de développement. Ils offrent un meilleur niveau de performance en contre partie d’un certain nombre de restrictions sur le modèle généré Data baseObjectsMapping O/RInfos de mappingInfos de mapping
Etat de l’art: les générateursDatabase Centric: type OlymarsGénérateurDéveloppementExécutionData baseObjectsInfos de mapping
Etat de l’art: les générateursObject Centric: type DTM (Evaluant)GénérateurDéveloppementExécutionData baseObjectsInfos de mapping
Que recherchons nous vraiment ?Automatisation de la DALPerformanceConsommation mémoireProductivitéOutil de conceptionAbstraction de la baseGestion du changement?ConstatNous avons tous des attentes différentes
Nous savons que cette couche est déterminante
Beaucoup de solutions et beaucoup de polémiquesDemoSans rien…
ModélisationBase de donnéesTables, colonnes, types simplesClés: primaires, étrangères, composites, indexesRelationsHéritageObjetsClasses, champs, propriétésCompositions (types complexes), portéesRelationsHéritage: relationnel ou nonModèle physique et conceptuelLes objets plus proches du modèle conceptuel
Demo…avec des objets
ArchitectureOrganisation en couchesDAL: data abstraction layerBusiness/Rules: couche métierPrésentation: interface utilisateur (windows/web, autre)DistributionPossibilité de distribuer la couche DAL: choix complexe et déterminantChoix d’un modèle communiquant (MarshalByRef)Choix d’un modèle externe: sérialisation personnalisée ou génération d’un modèle communiquantCette possibilité est souvent ignorée. Il devient pourtant rapidement tentant d’offrir cette couche basse de l’architecture au reste d’un modèle distribuéIl est important de poser cette question au plus tôt car les contraintes sont nombreuses (sérialisation, cache distribué, threadsafe ?, sessions, transactions « mémoire »)
ArchitectureModèles d’implémentationModèle répétitifChaque couche définit ses objets/interfaces:Avantages: indépendance totaleInconvénients: gourmand et complexeModèle navigantLes différentes couches d’échangent un unique objet persistantAvantages: un seul objet à concevoir, pas de duplication mémoire, simpleInconvénients: dépendance entre les couches (l’abstraction via des interfaces permet au moins de libérer la dépendance binaire)EnjeuxConcevoir dès la phase de définition d’architecture la nature précise de cette coucheLa possibilité de rendre les objets distribuables ainsi que les choix de dépendance (interfaces, portées) sont souvent des contraintes importantes d’une architecture d’implémentation.
DemoOrganisation en couches
Fonctionnalités attendues de la couche objetDonnéesRelations/NavigationRequêtesTransactionCacheMise en œuvre
Fonctionnalités attendues de la couche objet:DonnéesGestion de la nullité: data == System.DBNull.Value ?Object: boxing/unboxing (non typé)SqlTypesNullables: int?Projection variableAssocier des chargements de colonnes variables dans vers une même classe: « SELECT FIELD1, FIELD2,…, FIELDN FROM… »Le « SELECT * » n’est pas toujours faisable (données trop grandes, blob), modifier le modèle n’est pas la solutionVersionning de donnéesPouvoir jongler avec plusieurs jeux de données d’un même objet: AcceptChanges/RejectChanges
DemoGestion de la nullité
DemoVersionning
Fonctionnalités attendues de la couche objet:DonnéesSuivi des modificationsMettre en œuvre un moyen de tracer toutes les modifications sur les objets persistants:Notification au niveau des propriétés: pattern « PropertyNameChanged », INotifyPropertyChangedNotification sur les collections: CRUD (Create, Update, Delete)Le système est coûteux et non générique même s’il y a un mieux avec INotifyPropertyChanged (.Net 2.0)DatabindingEn WinForms ou WebFormsLe mapping objet relationnel tente d’automatiser la DAL, essayons de ne pas perdre le databinding !Respect des interfaces de binding: IList, IBindingList, etc…
DemoSuivi des changements
Fonctionnalités attendues de la couche objet:Relations/NavigationNavigationChargements en cascadeLazzyLoadingChargement à la demande lors de la navigation: client.Orders[0].DateParamétrageCollectionsChaînage des appels entre collections et élémentsIntégritéProfiter des informations relationnelles de mapping pour valider l’intégrité d’un graphe d’objet (de nombreuses notifications sont alors nécessaires)
Fonctionnalités attendues de la couche objet:RequêtesGénération automatiques des requêtes CRUDDynamique: à la demandeStatique: lors de la génération (si le modèle le propose)ProblématiquesPerformance ?Procédures stockées, vues ?Accès total à la vue physique de la base de données: sécurité ?SémantiqueAvoir un langage unique pour requêter en mémoire parmi les objets ou vers la base de données grâce aux informations de mapping: OQL ? XPath ? Linq ? 
Fonctionnalités attendues de la couche objet:TransactionPossibilité de travailler de manière transactionnelle sur un graphe d’objets persistantsNotion de session nécessaire même dans un environnement non distribuéIsolation des modifications par client (idem base de données)Implémentation des actions Commit et Rollback sur le grapheNouveautéProfiter du namespace System.Transaction de .Net 2.0Exemple de dataset transactionnel: http://www.techheadbrothers.com/DesktopDefault.aspx?tabindex=1&tabid=7&AId=120
Fonctionnalités attendues de la couche objet:CacheLes solutions de mapping O/R imposent par définition le mode déconnectéCréer ou ne pas recréer un objet déjà chargé ? Avantages et inconvénientsUne ClasseFactory facilite normalement le branchement d’un cache d’objet (unicité de la création)Définir les données du cache, sa stratégieVersionningExemple de mise en œuvreA la limite du garbage collector
DemoMise en œuvre d’une solution de cache
Fonctionnalités attendues de la couche objet:Mise en œuvreMappingPar attributsAvantages: lié au code, intégritéInconvénients: lié au codePar fichier externeAvantages: indépendance du code, possibilité de fournir plusieurs versionsInconvénients: pas intègreAjout de fonctionnalitésPar classe partielle: facile mais non objetPar héritage: classe de baseAOP:Dynamique, par interception: MarshalByRefPar tissage: AOP
DemoInterception de méthode: MarshalByRef
DemoPremier mapping
ProductivitéOutilsExternalisation des informations: mapping, méta-donnéesGénérateurs: de schémas de base de données, de classesConception visuelleExtensibilité de Visual StudioAddinsWizardsDesignersProject & item templates
MySolution: DSMap, un DataSet objet ?!?!Pourquoi développer sa propre solution:Appréhender la difficulté ?Mettre en place une solution originale ?Etre plus apte à juger les produits existants ?Conclure qu’il vaut mieux utiliser une solution du marché ?Coller au mieux à ses besoins ?Vous faire partager l’expérienceSe coller des cernes la veille d’une présentation technique rue de l’Université ?
Solution proposée : objectifsAvoir une solution indépendante de la source de donnéesEtre proche de la performance et de la consommation mémoire d’un modèle RAD avec chargement direct dans un DataSetConserver les fonctionnalités de « DataBinding » et d’utilisation en mode « design »Fournir à la couche métier une unique interface d’accès aux données entièrement objet
Solution proposée : avantagesSolution entièrement .Net car s’appuyant sur les DataSets.Modèle indépendant de la source de données (base, xml, mémoire).Chargement unique des données en mémoire dans un DataSet, le reste des classes persistantes offrant uniquement des accesseurs.
Solution proposée : avantagesCréation entièrement dynamique des collections et des éléments lors d’un parcours d’un graphe d’objets.Plusieurs modes de création automatique des objets : systématique, cache.Avoir des accesseurs non publics, en lecture, écriture ou lecture/écriture
Solution proposée : avantagesCharger un nombre de colonnes variable dans un même objet mappéSupport du foreach pour les collectionsSupport du DataBinding des objets et des collectionsSupport du binding complexe vers les propriétés et les sous-propriétés d’un objet persistant (DataMember)
Solution proposée : avantagesHéritage de classes
Support des collections hétérogènes avec classes héritées
Mises à jours vers la base (Create, Update, Delete) via les fonctionnalités classiques des DataSets (requêtes auto-générées ou personnalisées)Solution proposée : contraintesSolution entièrement .Net car s’appuyant sur les DataSetsClasses de base imposées pour les collections et les élémentsChargement des clés primaires et étrangères obligatoires
DemoRappels
Solution proposée : architectureInfos mappingCommands, DataAdaptersInfos mappingRelationalDataAdapterCRUDDataMappingInfos mappingpar attributs
Par codeIDBContextDBContextIDataSetProviderIAutoUpdateMauvaise nouvelleIL FAUT CODER !!!Data baseXmlDataSetObjectsMémoireSqlDBContextOracleDBContextADODBContext
DataTableDataSetSolution proposée : architectureDataClassCollectionDataClassPropertyDataTableData sourceDataTableDataViewFieldDataRowView(Client)(Client.Nom)(Clients[])
Solution proposée : architecturedataView[]DataRowViewDataClass IList.this[int index]DataRowViewDataRowViewRéécriture de l’interface IList afin de retourner une instance de DataClass au lieu de DataRowView.class Client :DataRowView row[DataClass(«ID»)]class ClientCollection :DataClassCollection,IEnumerable, ICollection, IListClient this[int index] {  get {    return GetItem(index);  }}DataClassString Nom {  get {    return row[«NAME»];  }}
Solution proposée :mapping simpleClient : DataClassString Nom{  get   {    return (string) row[«NAME»];  }  set  {    row[«NAME»] = value;  }}
Solution proposée :mapping de relationsClient : DataClass[DataClassRelation("customerid", "customerid")]public CommandeCollection Commandes {  get  {     return (CommandeCollection) this.relations["Commandes"];  }}[DataClassRelation(“(customerid=@custumerid) and (state = 1)")]public CommandeCollection CommandesLivrees {  get  {     return (CommandeCollection) this.relations["Commandes"];  }}
Solution proposée :mapping de référencesCommande : DataClass[DataClassReference("customerid", "customerid")]public Client Client {    get { return (Client) this.references["Client"]; }}

Mappingobjetrelationnel[1]

  • 1.
    Mapping objet relationnelMitsuruFURUTA – Microsoft Francemitsufu@microsoft.comhttp://blogs.microsoft.fr/mitsufu
  • 2.
    Objectifs de laprésentationC’est une présentation technique !Appréhender les conceptsComprendre les problématiquesEtre capable d’évaluer un produitMettre en œuvre les principes fondamentaux sous forme de courtes démosPas de présentation de produitPas de parti prisPas de LINQ…C’est une présentation technique !
  • 3.
    Mapping objet relationnelIntroductionModélisationArchitectureFonctionnalitésattendues de la couche objetProductivitéMySolution: DSMap, un DataSet objet…La pause ? Quelle pause ?
  • 4.
    IntroductionEnjeux et problématiquesDatabase!= objectsArchitecture multi-couche: DAL, business, présentationEst-il possible d’automatiser la DAL ?Amener la persistance aux objets métiersModélisationRecherche du modèle uniqueRequêtageTuer le SQLImplémentationsOutils ou framework ?Modèle intrusif ou pasSolutions souvent techniquesGénération de code: templates dynamiques, CodeDomAbstraction: proxy dynamique, tissage
  • 5.
    IntroductionIdéal ?Le purmapping O/R ne requiert aucun prérequis ni de la part de la base ni de la part de la couche objet. Il assure le lien entre les deux quelques soient les modèles.La solution assure en général l’accès à la base et la création automatiques des objets (classFactory).Les solutions sont en général riches mais coûteuses en ressources et en performances.Data baseObjectsMapping O/R
  • 6.
    IntroductionRéalitéDe nombreuses solutionsont le parti pris de se baser soit sur la base soit sur les objets. Les informations de mapping accompagnent alors le modèle choisi et servent à générer le modèle opposée (la base ou les objets)Ces modèles s’utilisent dans la phase de développement. Ils offrent un meilleur niveau de performance en contre partie d’un certain nombre de restrictions sur le modèle généré Data baseObjectsMapping O/RInfos de mappingInfos de mapping
  • 7.
    Etat de l’art:les générateursDatabase Centric: type OlymarsGénérateurDéveloppementExécutionData baseObjectsInfos de mapping
  • 8.
    Etat de l’art:les générateursObject Centric: type DTM (Evaluant)GénérateurDéveloppementExécutionData baseObjectsInfos de mapping
  • 9.
    Que recherchons nousvraiment ?Automatisation de la DALPerformanceConsommation mémoireProductivitéOutil de conceptionAbstraction de la baseGestion du changement?ConstatNous avons tous des attentes différentes
  • 10.
    Nous savons quecette couche est déterminante
  • 11.
    Beaucoup de solutionset beaucoup de polémiquesDemoSans rien…
  • 12.
    ModélisationBase de donnéesTables,colonnes, types simplesClés: primaires, étrangères, composites, indexesRelationsHéritageObjetsClasses, champs, propriétésCompositions (types complexes), portéesRelationsHéritage: relationnel ou nonModèle physique et conceptuelLes objets plus proches du modèle conceptuel
  • 13.
  • 14.
    ArchitectureOrganisation en couchesDAL:data abstraction layerBusiness/Rules: couche métierPrésentation: interface utilisateur (windows/web, autre)DistributionPossibilité de distribuer la couche DAL: choix complexe et déterminantChoix d’un modèle communiquant (MarshalByRef)Choix d’un modèle externe: sérialisation personnalisée ou génération d’un modèle communiquantCette possibilité est souvent ignorée. Il devient pourtant rapidement tentant d’offrir cette couche basse de l’architecture au reste d’un modèle distribuéIl est important de poser cette question au plus tôt car les contraintes sont nombreuses (sérialisation, cache distribué, threadsafe ?, sessions, transactions « mémoire »)
  • 15.
    ArchitectureModèles d’implémentationModèle répétitifChaquecouche définit ses objets/interfaces:Avantages: indépendance totaleInconvénients: gourmand et complexeModèle navigantLes différentes couches d’échangent un unique objet persistantAvantages: un seul objet à concevoir, pas de duplication mémoire, simpleInconvénients: dépendance entre les couches (l’abstraction via des interfaces permet au moins de libérer la dépendance binaire)EnjeuxConcevoir dès la phase de définition d’architecture la nature précise de cette coucheLa possibilité de rendre les objets distribuables ainsi que les choix de dépendance (interfaces, portées) sont souvent des contraintes importantes d’une architecture d’implémentation.
  • 16.
  • 17.
    Fonctionnalités attendues dela couche objetDonnéesRelations/NavigationRequêtesTransactionCacheMise en œuvre
  • 18.
    Fonctionnalités attendues dela couche objet:DonnéesGestion de la nullité: data == System.DBNull.Value ?Object: boxing/unboxing (non typé)SqlTypesNullables: int?Projection variableAssocier des chargements de colonnes variables dans vers une même classe: « SELECT FIELD1, FIELD2,…, FIELDN FROM… »Le « SELECT * » n’est pas toujours faisable (données trop grandes, blob), modifier le modèle n’est pas la solutionVersionning de donnéesPouvoir jongler avec plusieurs jeux de données d’un même objet: AcceptChanges/RejectChanges
  • 19.
  • 20.
  • 21.
    Fonctionnalités attendues dela couche objet:DonnéesSuivi des modificationsMettre en œuvre un moyen de tracer toutes les modifications sur les objets persistants:Notification au niveau des propriétés: pattern « PropertyNameChanged », INotifyPropertyChangedNotification sur les collections: CRUD (Create, Update, Delete)Le système est coûteux et non générique même s’il y a un mieux avec INotifyPropertyChanged (.Net 2.0)DatabindingEn WinForms ou WebFormsLe mapping objet relationnel tente d’automatiser la DAL, essayons de ne pas perdre le databinding !Respect des interfaces de binding: IList, IBindingList, etc…
  • 22.
  • 23.
    Fonctionnalités attendues dela couche objet:Relations/NavigationNavigationChargements en cascadeLazzyLoadingChargement à la demande lors de la navigation: client.Orders[0].DateParamétrageCollectionsChaînage des appels entre collections et élémentsIntégritéProfiter des informations relationnelles de mapping pour valider l’intégrité d’un graphe d’objet (de nombreuses notifications sont alors nécessaires)
  • 24.
    Fonctionnalités attendues dela couche objet:RequêtesGénération automatiques des requêtes CRUDDynamique: à la demandeStatique: lors de la génération (si le modèle le propose)ProblématiquesPerformance ?Procédures stockées, vues ?Accès total à la vue physique de la base de données: sécurité ?SémantiqueAvoir un langage unique pour requêter en mémoire parmi les objets ou vers la base de données grâce aux informations de mapping: OQL ? XPath ? Linq ? 
  • 25.
    Fonctionnalités attendues dela couche objet:TransactionPossibilité de travailler de manière transactionnelle sur un graphe d’objets persistantsNotion de session nécessaire même dans un environnement non distribuéIsolation des modifications par client (idem base de données)Implémentation des actions Commit et Rollback sur le grapheNouveautéProfiter du namespace System.Transaction de .Net 2.0Exemple de dataset transactionnel: http://www.techheadbrothers.com/DesktopDefault.aspx?tabindex=1&tabid=7&AId=120
  • 26.
    Fonctionnalités attendues dela couche objet:CacheLes solutions de mapping O/R imposent par définition le mode déconnectéCréer ou ne pas recréer un objet déjà chargé ? Avantages et inconvénientsUne ClasseFactory facilite normalement le branchement d’un cache d’objet (unicité de la création)Définir les données du cache, sa stratégieVersionningExemple de mise en œuvreA la limite du garbage collector
  • 27.
    DemoMise en œuvred’une solution de cache
  • 28.
    Fonctionnalités attendues dela couche objet:Mise en œuvreMappingPar attributsAvantages: lié au code, intégritéInconvénients: lié au codePar fichier externeAvantages: indépendance du code, possibilité de fournir plusieurs versionsInconvénients: pas intègreAjout de fonctionnalitésPar classe partielle: facile mais non objetPar héritage: classe de baseAOP:Dynamique, par interception: MarshalByRefPar tissage: AOP
  • 29.
  • 30.
  • 31.
    ProductivitéOutilsExternalisation des informations:mapping, méta-donnéesGénérateurs: de schémas de base de données, de classesConception visuelleExtensibilité de Visual StudioAddinsWizardsDesignersProject & item templates
  • 32.
    MySolution: DSMap, unDataSet objet ?!?!Pourquoi développer sa propre solution:Appréhender la difficulté ?Mettre en place une solution originale ?Etre plus apte à juger les produits existants ?Conclure qu’il vaut mieux utiliser une solution du marché ?Coller au mieux à ses besoins ?Vous faire partager l’expérienceSe coller des cernes la veille d’une présentation technique rue de l’Université ?
  • 33.
    Solution proposée :objectifsAvoir une solution indépendante de la source de donnéesEtre proche de la performance et de la consommation mémoire d’un modèle RAD avec chargement direct dans un DataSetConserver les fonctionnalités de « DataBinding » et d’utilisation en mode « design »Fournir à la couche métier une unique interface d’accès aux données entièrement objet
  • 34.
    Solution proposée :avantagesSolution entièrement .Net car s’appuyant sur les DataSets.Modèle indépendant de la source de données (base, xml, mémoire).Chargement unique des données en mémoire dans un DataSet, le reste des classes persistantes offrant uniquement des accesseurs.
  • 35.
    Solution proposée :avantagesCréation entièrement dynamique des collections et des éléments lors d’un parcours d’un graphe d’objets.Plusieurs modes de création automatique des objets : systématique, cache.Avoir des accesseurs non publics, en lecture, écriture ou lecture/écriture
  • 36.
    Solution proposée :avantagesCharger un nombre de colonnes variable dans un même objet mappéSupport du foreach pour les collectionsSupport du DataBinding des objets et des collectionsSupport du binding complexe vers les propriétés et les sous-propriétés d’un objet persistant (DataMember)
  • 37.
    Solution proposée :avantagesHéritage de classes
  • 38.
    Support des collectionshétérogènes avec classes héritées
  • 39.
    Mises à joursvers la base (Create, Update, Delete) via les fonctionnalités classiques des DataSets (requêtes auto-générées ou personnalisées)Solution proposée : contraintesSolution entièrement .Net car s’appuyant sur les DataSetsClasses de base imposées pour les collections et les élémentsChargement des clés primaires et étrangères obligatoires
  • 40.
  • 41.
    Solution proposée :architectureInfos mappingCommands, DataAdaptersInfos mappingRelationalDataAdapterCRUDDataMappingInfos mappingpar attributs
  • 42.
    Par codeIDBContextDBContextIDataSetProviderIAutoUpdateMauvaise nouvelleILFAUT CODER !!!Data baseXmlDataSetObjectsMémoireSqlDBContextOracleDBContextADODBContext
  • 43.
    DataTableDataSetSolution proposée :architectureDataClassCollectionDataClassPropertyDataTableData sourceDataTableDataViewFieldDataRowView(Client)(Client.Nom)(Clients[])
  • 44.
    Solution proposée :architecturedataView[]DataRowViewDataClass IList.this[int index]DataRowViewDataRowViewRéécriture de l’interface IList afin de retourner une instance de DataClass au lieu de DataRowView.class Client :DataRowView row[DataClass(«ID»)]class ClientCollection :DataClassCollection,IEnumerable, ICollection, IListClient this[int index] { get { return GetItem(index); }}DataClassString Nom { get { return row[«NAME»]; }}
  • 45.
    Solution proposée :mappingsimpleClient : DataClassString Nom{ get { return (string) row[«NAME»]; } set { row[«NAME»] = value; }}
  • 46.
    Solution proposée :mappingde relationsClient : DataClass[DataClassRelation("customerid", "customerid")]public CommandeCollection Commandes { get { return (CommandeCollection) this.relations["Commandes"]; }}[DataClassRelation(“(customerid=@custumerid) and (state = 1)")]public CommandeCollection CommandesLivrees { get { return (CommandeCollection) this.relations["Commandes"]; }}
  • 47.
    Solution proposée :mappingde référencesCommande : DataClass[DataClassReference("customerid", "customerid")]public Client Client { get { return (Client) this.references["Client"]; }}