Le développeur portugais Ricardo Peres a publié une comparaison apparemment objective des principaux ORMs .NET : NHibernate et Entity Framework. Bien que nous recommandions à tous de tenir compte de son article, Differences Between NHibernate and Entity Framework, nous allons travailler sur quelques différences clés.
Du point de vue de l'architecture, NHibernate est basé sur l'ORM Java Hibernate. Ricardo écrit,
Dans NHibernate, il y a une séparation entre l'Unit of Work, la configuration et les instances du modèle. Vous commencez par créer un objet Configuration dans lequel vous spécifiez tous les paramètres globaux NHibernate comme la base de données et le dialecte à utiliser, les tailles de batch, les mappings etc... Puis, à partir de ces paramètres, vous construisez une ISessionFactory. Cette dernière contient le modèle et les métadonnées liés à une base de données particulière et aux paramètres issus de l'objet Configuration, et il n'y aura typiquement qu'une seule instance de chaque dans un process. Finalement, vous créez des instances de ISession à partir de ISessionFactory, qui est la représentation NHibernate de l'Unit of Work et de l'Identity Map. C'est un objet léger qui, essentiellement, ouvre et ferme une connexion à une base de données au besoin, et garde un suivi des entités qui lui sont rattachées. La création et la destruction d'objets de type ISession sont peu coûteuses, car toute la complexité du modèle est située au niveau de ISessionFactory et des objets Configuration.
Morten Mertner ajoute, "NH n'a jamais été capable de me convaincre. Il contient une liste impressionnante de fonctionnalités, mais ce n'est pas un produit facile d'utilisation et, son API et sa conception gardent une trace de son héritage de Java (de la même manière que beaucoup d'APIs Java sont trop "enterpricey" et trop compliquées; YMMW)."
Entity Framework suit une conception .NET plus traditionnelle où tout est encapsulé dans un seul ObjectContext ou DbContext. Cela rend l'utilisation de ce dernier beaucoup plus simple, mais l'inconvénient est que "la classe n'est par conséquent pas aussi légère que son équivalent NHibernate et il n'est pas rare de voir des exemples de mise en cache d'une instance dans un champ."
Concernant le mapping, une différence clé entre NHibernate et EntityFramework vient du fait que le premier supporte les fichiers de mapping XML déployés séparément. En théorie, cela permet de manipuler le même modèle objet sur des schémas de base de données différents, sans avoir à recompiler l'application. En pratique, cela n'est que rarement utilisé.
Il y a plusieurs domaines sur lesquels le plus ancien des deux, NHibernate, est en avance par rapport à Entity Framework. Ricardo apporte plus de détails, mais les voici brièvement :
- Associations : Les 2 supportent les associations one to one, one to many et many to many, mais NHibernate supporte aussi les collections ordonnées, non ordonnées et indexées. Il dispose même d'une liste immuable et indéxée.
- Caching : NHibernate offre un cache de deuxième niveau disposant de nombreuses implémentations. Entity Framework n'a aucune prise en charge intégrée pour cela, mais il existe des exemples d'ajout de caching de deuxième niveau.
- Génération d'ID : NHibernate offre à peu près une douzaine de stratégies de génération selon comment vous les comptez. Entity Framework ne propose que les 3 principales pour SQL Server : "identity columns", GUIDs et attribution manuelle.
- Evénements : Entity Framework n'a que deux points d'extension orientés événements : ObjectMaterialized et SavingChanges. "Le modèle événementiel de NHibernate est très riche, il expose plus de 20 événements, soit pour la pré-exécution synchrone soit pour la post-exécution asynchrone".
- Cascading : "Les deux supportent le cascading de collection et d'association : lorsqu'une entité est supprimée, ses enfants le sont aussi. NHibernate offre également la possibilité de positionner la colonne de clé étrangère des enfants à NULL au lieu de les supprimer".
- Propagation des changements : NHibernate propose un mode automatique dans lequel les modifications sont enregistrées lorsque nécessaire, par exemple lorsqu'"une requête est lancée sur des instances "dirty" d'un type d'entité". FlushMode.Auto est en fait le comportement par défaut, mais il n'est pas rare de voir l'auto-flushing être critiqué à cause de ses problèmes de performance.
Il y a quelques domaines où Entity Framework est actuellement au-dessus de NHibernate :
- Suivi des modifications : Alors que les 2 ont un suivi de modification au niveau de l'Unit of Work, Entity Framework permet également un auto-suivi des entités.
- Intégration : Entity Framework a évidemment des liens étroits avec Visual Studio et divers librairies ASP.NET et WCF.
- Documentation : "C'est un autre point où Entity Framework est supérieur : NHibernate manque, pour les débutants, d'une API de référence à jour et synchronisée avec la version actuelle."
- Requêtes : Craig écrit, "NHibernate est beaucoup plus riche en terme de fonctionnalités, excepté sur un domaine, le support de Linq. Parce que Linq ou tout autre langage de requête est la partie la plus visible d'un ORM pour beaucoup d'utilisateurs, cela donne une mauvaise impression de son potentiel."
Il y a quelques domaines, comme le batching, sur lesquels les 2 ORMs pourraient s'améliorer. Et aucun ne se rapproche de SQL Alchemy lorsqu'il s'agit de réellement tirer profit des fonctionnalités SQL avancées comme les expressions de table commune.
Il convient de noter que les 2 projets sont complètement actifs et qu'ils apportent assez régulièrement des améliorations. Donc si les 2 répondent à vos exigences minimales, alors vous devriez davantage vous concentrez sur les design patterns et la philosophie des librairies plutôt que sur la liste des fonctionnalités.