Qu’est-ce qu’un ORM ?

Un mapping objet-relationnel (en anglais object-relational mapping ou ORM) est une technique de programmation informatique qui crée l’illusion d’une base de données orientée objet à partir d’une base de données relationnelle en définissant des correspondances (mapping) entre cette base de données et les objets du langage utilisé. On pourrait le désigner par « correspondance entre monde objet et monde relationnel ». (source : Wikipedia)

Ces solutions ont notamment pour objet de générer une couche de persistance robuste, pérenne et évolutive.

Quelle est la situation dans le monde .NET ?

Comme souvent pour les sujets d’industrialisation et de best pratices, le monde .NET connait un retard d’adoption par rapport au monde Java. Ce retard est en bonne partie imputable au retard pris par l’arrivée de solutions matures et exploitables proposées par Microsoft. Le corollaire de cette constatation est une hétérogénéité dans les modes d’accès aux données par l’applicatif. On retrouve notamment :

  • Microsoft ADO.NET : querystrings, procédures stockées
  • Microsoft Enterprise Library
  • ORM custom
  • ORM du marché

Quels sont les principaux freins à l’adoption d’un ORM ?

Il existe 5 raisons principales, d’ordre techniques, managériales et même organisationnelles :

  • La peur de la perte de contrôle sur les données : performances, non-maîtrise des requêtes générées automatiquement… C’est l’effet boîte noire.
  • De mauvais réflexes consistant à penser qu’un ORM n’est utile que pour les gros projets.
  • Une courbe d’apprentissage plus ou moins élevée selon le framework choisi.
  • Les ressources compétentes en SQL sont nombreuses.
  • Clivage possible entre les équipes études et les équipes DBA / Production

Bien que chacune de ces raisons puisse être justifiée, aucun de ces points n’est fondamentalement bloquant et des solutions de contournement peuvent être adoptées.

Pourquoi il faut tout de même y aller ?

La réponse à cette question est un simple calcul de retour sur investissement. Voici les paramètres essentiels d’évaluation de ce ROI :

  • Gain en productivité des développeurs : combien de temps est passé à réinventer la roue ?
  • Diminution du risque de dérapage et d’accumulation de dette technique par l’utilisation de best practices. Le coût de maintenance à moyen-long terme peut s’en retrouver sensiblement diminué.
  • Customisation possible avec les ORM modernes. Chaque organisation et chaque besoin étant unique, il est fondamental de pouvoir adapter ce type d’outil au contexte.
  • Flexibilité : développement « data driven » ou « class driven ». Tous les ORM permettent de partir de la base de données pour générer le modèle objet. Mais certains permettent de partir d’un modèle objet existant pour redescendre vers la base de données et d’en générer un script de création.

Toutefois, ne pas perdre de vue que…

… il y a toujours une base de données sur laquelle repose le stockage, et qu’il est nécessaire de connaître ses mécanismes et les concepts inhérents. En effet, une des principales dérives possibles est l’abstraction pure et simple pour les développeurs de la base de données. Or la base de données est, et restera, un point clé de la performance applicative. L’optimisation de requêtes, la gestion des concurrences d’accès, la maintien de l’intégrité des données resteront des éléments de réflexion et des points d’attention essentiels.

Comme pour tout framework, l’utilisation d’un ORM génère une courbe d’apprentissage. Il est important de le comprendre et d’assimiler ses concepts et les design patterns utilisés (Active Record, DataMapper…). Il faut voir cet état de fait comme un investissement.

Où se trouve la vérité ?

Comme souvent, dans le compromis.
Entre tout développer à la main et confier l’intégralité des interactions avec la BDD à un outil, il existe un juste milieu !
Il est possible de concilier le meilleur des deux mondes.

Notre expérience sur le sujet nous conduit à estimer :

  • 95% des requêtes simples et non-critiques sont confiées à l’outil, générant un gain en productivité.
  • 5% des requêtes critiques et nécessitant un tuning SQL feront l’objet de procédures stockées exécutées par l’ORM, permettant de garder le contrôle sur l’accès aux données et les performances.

Panorama des solutions

A- L’historique : NHibernate

Avantages

  • Maturité
  • Robustesse
  • Fort degré de customisation

Inconvénients

  • Paramétrage fastidieux (XML)
  • Performances
  • Difficulté au débuggage
  • Courbe d’apprentissage très forte
  • Pas de support de Linq
  • Dépendance à un projet open-source

B- La première solution Microsoft : Linq To Sql

Avantages

  • Intégré au framework .NET et au designer de Visual Studio
  • Customisation (procédures stockées, lazy load…)
  • Simplicité d’utilisation (Linq…)
  • Rapidité de mise en œuvre
  • Performances

Inconvénients

  • Limité à SqlServer
  • Mapping limité  1 table = 1 classe
  • Nécessite .NET 3.5+

C- La grosse artillerie Microsoft : Entity Framework

Avantages

  • Solution privilégiée par MS, sorte de Linq To Sql v2.0
  • Simplicité d’utilisation
  • Simplicité de mise en œuvre
  • Customisation très poussée : lazy load, héritage de tables, développement « class driven » ou « data driven »

Inconvénients

  • Performances légèrement en deça de Linq To Sql
  • Nécessite .NET 3.5+
  • Complexité parfois masquée par une interface simple (comme souvent avec les outils Microsoft)

D- L’outsider: Subsonic

Avantages

  • Légèreté
  • Compatibilité avec Linq depuis la v3
  • Simplicité de mise en œuvre

Inconvénients

  • Dépendance d’un éditeur tiers
  • Fonctionne par convention plutôt que par configuration, d’où une customisation moins poussée
  • Utilisation limitée des procédures stockées

E- Mais aussi…

Des projets plus marginaux existent, parfois fournis en open-source :

  • Microsoft DataSet typés
  • BL Toolkit
  • DataObjects.NET
  • LinqConnect
  • Telerik OpenAccess

Comment choisir ?

Le choix d’un ORM, s’il est bien choisi et correctement implémenté, n’est ni irrémédiable ni définitif. Il est toutefois très structurant. Parfois pour des raisons techniques (un ORM basé sur le design pattern ActiveRecord), mais le plus souvent pour des raisons d’impact sur la productivité de l’équipe et de réinvestissement.

Il est donc important de se poser un certain nombre de questions avant de se lancer :

  • Taille du projet (j-h) :  10j, 30j, 100+j ?
  • Politique DT/DSI : full Microsoft ou intégration d’outils tiers ?
  • Base de données : SQL Server ou autre ?
  • Class driven design ?
  • Temps alloué pour la prise en mains ?
  • L’équipe est-elle familière avec  Linq ?
  • Quelles sont les contraintes de performances ?
  • Quelles sont les contraintes liées à l’infrastructure, la production et l’administration des bases de données ?

Pour les “petits” projets SqlServer “from scratch” : Linq To Sql

  • Rapidité de mise en œuvre : designer
  • Robustesse
  • Performances / évolutivité

Pour les “gros” projets / “grands” projets : Entity Framework

  • Pérennité de la solution, support à long terme
  • Evolution rapide (déjà en v4)
  • Customisation poussée
  • Mise en œuvre facilitée par le designer

Conclusion : Peut-on se passer des solutions Microsoft ?

C’est difficile. Ces dernières solutions sont matures, pérennes et bénéficient de leur forte intégration au Framework .NET et à Visual Studio. Un autre élément à prendre en compte est que si les solutions tierces existent, c’est principalement parce que Microsoft a pris son temps pour développer les siennes. Depuis l’apparition de Linq To Sql et surtout Entity Framework, le marché s’est brutalement tassé. Le nombre d’ORM pour .NET était auparavant bien plus élevé. Aujourd’hui, beaucoup sont abandonnés, et peu demeurent.

Mais il faut garder à l’esprit que de vraies solutions tierces existent.

Sources :

Wikipedia FR / Wikipedia EN

ActiveRecord et DataMapper par Martin Fowler

Pourquoi utiliser des ORM en .NET par Philippe Vialatte