Entity Framework 4 vs NHibernate [fermé]

114

On a beaucoup parlé de la première version d'Entity Framework sur le Web (également sur stackoverflow) et il est clair que ce n'était pas un bon choix alors que nous avons déjà une meilleure alternative comme NHibernate. Mais je ne trouve pas de bonne comparaison entre Entity Framework 4 et NHibernate. Nous pouvons dire qu'aujourd'hui NHibernate est le leader parmi tous les ORM .NET, mais pouvons-nous nous attendre à ce qu'Entity Framework 4 déplace NHibernate de cette position. Je pense que si Microsoft a vraiment injecté de très bonnes fonctionnalités dans EF4, cela peut donner une bonne concurrence à NHibernate car il a l'intégration de Visual Studio, plus facile à travailler et la préférence est toujours donnée aux produits MS dans la plupart des magasins.

Deependra Solanky
la source
31
J'aimerais une mise à jour de cette comparaison. Est-ce qu'il s'est passé beaucoup de choses depuis '09?
Phil

Réponses:

66

EF4 a une réponse prête à l'emploi en ce qui concerne le développement à n niveaux, dans les «entités auto-suiveuses». Personne n'a publié de code comparable pour NHib.

NHib a de nombreuses fonctionnalités qui n'ont pas été mentionnées comme faisant partie d'EF4. Celles-ci incluent l'intégration du cache de deuxième niveau. Il offre également une plus grande flexibilité dans le mappage d'héritage, une meilleure intégration avec les procédures stockées / les fonctions de base de données / SQL personnalisé / les déclencheurs, la prise en charge des propriétés de formule, etc. IMO est fondamentalement juste plus mature en tant qu'ORM.

John Rayner
la source
13
+1 Vous avez raison. NH est juste mature. EF rattrapera son retard d'ici la fin de l'année. La version 4.0 a déjà fait une entrée spectaculaire. Donnez-lui un peu de temps et il sera à l'épreuve des balles d'ici la mi-2011.
15
-1 Pour "EF4 a une réponse prête à l'emploi en ce qui concerne le développement n-tiers, dans les" entités d'auto-suivi ". Personne n'a publié de code comparable pour NHib." Il y a ISession.Merge dans NHibernate qui est beaucoup mieux que les entités Self-Tracking pour le développement N-Tier pour de nombreuses raisons.
Alex Burtsev
12
@Alex - En quoi NHibernate est-il une solution «prête à l'emploi»? Juste pour clarifier; «Out of the box» signifie qu'il fonctionne avec une installation vanilla de Visual Studio. C'est un -1 injustifié ici.
Doctor Jones
9
@DoctaJonez - La façon dont je l'ai lu, Alex contestait l'idée que NH n'a rien de comparable aux entités auto-pistées, pas le fait que cela soit «prêt à l'emploi».
Jerph
2
En fait, j'ai découvert qu'EF4 a un mappage d'héritage plus flexible. Par exemple, vous pouvez utiliser 2 tables (TPT) comme classe de base + classe de niveau 1 et ajouter un discriminateur à la table de niveau 1, permettant le fractionnement en classes de niveau 2. Dans NH, le discriminateur ne peut être défini que sur la classe de base.
Danny Varod
37

Mise à jour: je n'ai pas utilisé Entity Framework depuis la version 4.0, donc ma réponse peut être obsolète. J'utilise toujours NH ou ADO pur .NET dans mes projets. Et je ne veux même pas regarder ce qui est nouveau dans EF depuis 4.0, car NH fonctionne parfaitement.

En fait, il est assez facile de les comparer lorsque vous avez utilisé les deux. Il existe de sérieuses limitations avec EF4, je peux en nommer quelques-unes que j'ai rencontrées par moi-même:

Problèmes EF4:

  • Chargement et mise en forme du résultat : le système de chargement impatient EF4 (Include ("Path")) génère du SQL incorrect, avec des JOIN en boucle, qui exécutera des milliers de fois (pas littéralement) plus lentement pour les relations plusieurs-à-plusieurs que du SQL écrit à la main (c'est effectivement inutilisable).
  • Materializer ne peut pas matérialiser les entités associées : si vous pensez pouvoir surmonter le problème précédent en fournissant votre propre requête SQL, vous vous trompez. EF4 ne peut pas matérialiser (mapper) les entités associées à partir de la requête SQL JOIN, il ne peut charger les données que d'une table (donc si vous avez Order.Product, SELECT * FROM order LEFT JOIN Le produit initialisera uniquement l'objet Order, le produit restera nul, pensé que toutes les données nécessaires sont récupérées dans la requête pour l'initialiser). Cela peut être surmonté en utilisant le module complémentaire de la communauté EFExtensions, mais le code que vous devrez écrire pour cela est vraiment moche (j'ai essayé).
  • Entités d'auto-suivi: Beaucoup disent que les entités d'auto-suivi sont cool pour le développement N-tiers, y compris la réponse principale dans ce fil de discussion. Je pensais que je ne les ai même pas essayés, je peux dire qu'ils ne le sont pas.Chaque entrée peut être falsifiée, vous ne pouvez pas simplement prendre les modifications que l'utilisateur vous envoie et les appliquer à la base de données, pourquoi ne pas donner à l'utilisateur des données directes accès à la base alors? De toute façon, vous devrez charger les données que l'utilisateur est sur le point de changer de la base de données, vérifiez qu'elle existe | n'existe pas faites des vérifications d'autorisations, etc. Vous ne pouvez pas faire confiance à l'utilisateur sur l'état de l'entité qu'il envoie au serveur, vous le ferez de toute façon devez charger cette entité à partir de la base de données et déterminer son état et d'autres choses, donc ces informations sont inutiles, tout comme les entités d'auto-suivi à moins que vous ne fassiez un système à n-tiers de confiance privé à usage interne, auquel cas vous pourriez peut-être donner tout simplement Accès à la base de données.

  • Journalisation, événements, intégration de la logique métier: EF4 est comme une boîte noire, il fait quelque chose et vous n'avez aucune idée de ce qu'il fait. Il n'y a qu'un seul événement OnSavingChanges où vous pouvez mettre une logique métier dont vous avez besoin pour exécuter avant que quelque chose ne se passe avec DB, et si vous devez appliquer des modifications aux objets métier avant que quelque chose ne se produise, vous devrez creuser dans ObjectStateManager, et c'est vraiment moche , le code peut devenir énorme. Si, par exemple, vous utilisez le modèle de référentiel et que vous devez être notifié des modifications apportées à la base de données de manière propre, vous aurez du mal à le faire avec EF.

  • Extensibilité: tout le code EF est privé et interne, si vous n'aimez pas quelque chose (et que vous n'aimerez pas BEAUCOUP si vous êtes sérieux au sujet de l'utilisation d'EF), vous ne changerez pas cela facilement, en fait, je suis sûr il est plus facile d'écrire votre propre ORM à partir de zéro (je l'ai fait) puis de faire fonctionner EF comme vous le souhaitez. À titre d'exemple, jetez un œil à la source d'EFExtensions, elle est basée sur des méthodes d'extensions et différents "hacks" pour rendre EF un peu plus utilisable, et le code est assez moche (et ce n'est pas la faute des auteurs, quand tout dans EF est privé, c'est le seul façon de l'étendre).

Je peux continuer à écrire de mauvaises choses sur EF et à quel point cela a été douloureux pour moi de travailler avec environ 20 pages, et peut-être que je le ferai.

Et NHibernate? C'est un niveau absolument différent, c'est comme comparer PHP à C #, EF4 est comme à l'âge de pierre, c'est comme si EF avait 10 ans de retard, puis NHibernate en cours de développement, et en fait, Hibernate a été lancé en 2001. Si vous avez du temps libre pour apprendre et activer Nhibernate, faites-le.

Alex Burtsev
la source
1
EF a été publié sous la licence Apache 2, ce qui devrait aider à l'extensibilité.
CMircea
@MirceaChirea C'est une excellente nouvelle, je ne m'attendais pas à cela, en parcourant le code source d'EF en ce moment, une lecture assez intéressante.
Alex Burtsev
2
-1 pour avoir fait plusieurs déclarations précédées de "Je n'ai pas utilisé ceci, mais je parle quand même."
Kyeotic
@Tyrsius Ma réponse a été écrite, il y a presque 3 ans, je n'utilise pas EF depuis longtemps, certaines choses pourraient s'améliorer, vous pouvez modifier ma réponse pour la mettre à jour vers le statut EF actuel.
Alex Burtsev
2
Vous admettez que vous n'avez jamais utilisé d'entités de suivi automatique, mais vous les rejetez. Que diriez-vous de ne parler que de ce que vous savez et de laisser de côté les suppositions ignorantes, d'autant plus que tout ce paragraphe est à peu près faux.
Tom Halladay
25

Voici la chose. NHibernate et Entity Framework sont vraiment pour deux publics différents, dans mon esprit. NHibernate serait mon choix dans la construction d'un système avec des mappages complexes, des formules et des contraintes (essentiellement tout ce qui concerne l'entreprise). Si je voulais démarrer avec un accès simple aux données, j'utiliserais Entity Framework ou LINQ-to-SQL. NHibernate n'a pas une expérience de "glisser-déposer" claire tout à fait comme EF. Les deux ont leurs forces et leurs inconvénients. Les comparer des pommes aux pommes, franchement, ne vous mène nulle part.

zowens
la source
13
Avez-vous essayé ActiveWriter? Entity Framework est absolument destiné à l'espace d'entreprise. Je ne suis pas d'accord avec la plupart de ce que vous avez dit.
Michael Maddox
1
Pas d'accord tout ce que vous voulez, mais le fait que NHibernate existe depuis plus longtemps est quelque chose que les entreprises NE négligent PAS.
zowens
21
-1 Ce n'est pas une bonne comparaison entre NHibernate et Entity Framework. Comparer les deux en regroupant EF avec LINQ to SQL uniquement car il a glisser-déposer est au mieux malhonnête. En ce qui concerne la complexité, qu'est-ce que NHibernate peut faire exactement que EF 4 ne peut pas faire?
Kevin Babcock
14
Caching de deuxième niveau, leurs requêtes sont HAUTEMENT optimisées, NH vous oblige à utiliser le modèle UnitOfWork, et les mappages ne sont pas bloqués dans un seul fichier. Mon opinion (par expérience) est que NHibernate est plus performant. Je ne suis pas d'accord avec moi à ce sujet, mais j'ai dit que c'était mon opinion. Mon argument dans ma réponse est TOUJOURS valable, ils ont tous deux leurs forces et leurs faiblesses. Personne ne peut le nier.
zowens
2
@ MakerOfThings7 c'est pathétique ... toute cette question est subjective. Réveillez-vous ...
zowens
23

Si vous pensez que vous voudrez peut-être exécuter votre code sur Mono, NHibernate est probablement un meilleur choix, peu importe ce que disent les listes de contrôle des fonctionnalités ...

Modifier, 13/08/2012:

Entity Framework a été open-source et est désormais inclus dans Mono à partir de 2.11.3. Cette réponse est désormais dépassée et ne doit pas être invoquée.

http://weblogs.asp.net/scottgu/archive/2012/07/19/entity-framework-and-open-source.aspx

Joel Mueller
la source
En effet, sur mono-project.com/Compatibility, il lit "EntityFrameworks - Not available.", Et il semble que personne ne soit intéressé à l'implémenter. Donc au moins pendant quelques années, c'est NHibernate ou rien.
user276648
12

Mon point de vue est que EF4.0 a parcouru un long chemin depuis la version 1.0 et rattrape Nhibernate en termes de fonctionnalités, mais tout n'est pas encore là.

Cependant, c'est Microsoft, prêt à l'emploi, et faire 100% de ce que 95% des applications ont besoin de faire. Cependant, NHibernate fait la même chose depuis des années. La version 5.0 ou 6.0 pourrait rattraper, voire dépasser NHibernate.

Voici mon conseil - si vous avez le temps d'apprendre les deux, faites-le. Il y a plusieurs raisons de choisir l'un plutôt que l'autre. Si vous écrivez du code pour une entreprise, il est réaliste de s'attendre à être des employés compétents qui connaissent EF, car c'est dans tous les livres et ce que les enfants apprennent à l'université. Si EF répond à vos besoins (pensez à celui-ci longtemps et dur avant de simplement dire oui), alors c'est une solution parfaitement adaptée pour le moment, et dans quelques années, il pourrait (ok, très probablement) surpasser NHibernate.

NHibernate est un produit très mature avec quelques années sur EF et fera très probablement tout ce que vous voudriez faire et plus encore. C'est le meilleur ORM depuis un certain temps maintenant et beaucoup de gens l'utilisent.

doyen
la source
10

Je pense que le fait qu'EF 4 aura la possibilité d'utiliser POCO et le chargement différé sera très important. Je pourrais certainement le voir gagner du terrain avec la nouvelle version.

OuaisStu
la source
7
N'oubliez pas le support LINQ. NHibernate n'est toujours pas bon dans ce domaine.
Arnis Lapsa
1
@Arnis, pouvez-vous fournir des liens pour étayer cette opinion?
Michael Maddox
2
@Michael cela est évident lorsque vous parcourez les articles de blog d'Ayande sur le sujet. LINQ to NH est basé sur les critères API à l'heure actuelle. L'API de critères n'autorise pas certaines des fonctions de requête les plus complexes que HQL peut. La prochaine version de LINQ to NH utilisera HQL au lieu de l'API de critères.
zowens
5

Il y a une tendance évidente à augmenter la popularité d'EF sur NHibernate, voir l'image.

NHibernate vs Entity Framework

Tomas Kubes
la source
Quel est le point de votre réponse? yourlogicalfallacyis.com/bandwagon
Răzvan Flavius ​​Panda
Selon la tendance, les gens commencent à utiliser davantage EntityFramework sur Google au fil du temps. Et ils peuvent avoir de bonnes raisons pour cela. Peut-être commencé à être meilleur.
Tomas Kubes le
Cela pourrait être le cas, il se pourrait aussi que ce soit ce qui est proposé par défaut pour être utilisé par MS. De plus, l'outillage pour EF est assez bon.
Răzvan Flavius ​​Panda
4

Mes 2 cents: nous utilisons ef sur notre client de bureau pour certains cahing, etc. Un NHib côté serveur - utilisant des sessions sans état, la génération d'ID hilo et des lots. Is est assez rapide pour insérer 3k + messages en db par seconde. De plus, il est très flexible et prend en charge de nombreux dbs, ce qui est crucial pour notre produit.

Aleksei Anufriev
la source
3

Le mappage direct aux procédures stockées avec une combinaison de Linq pour une couche logique semble l'approche la plus simple. Pas de xml. Générez SQL uniquement pour les requêtes intéressantes qui sont moins fréquemment utilisées ou qui ne conviennent pas aux procédures stockées.

Les objets chargent et stockent via des SP standard. Cette approche permet l'utilisation de deux connexions SQL. Un pour l'accès aux classes via les SP (autorisations d'exécution uniquement) et un pour un module linq logique qui permet l'accès direct à la table.

Andrew
la source
1

Choisir entre les ORM par popularité n'est pas la meilleure chose à faire. J'ai essayé de passer à EF au cours des 2 dernières années et tout ce que je peux dire, c'est, pourquoi diable j'essaye encore de le faire?

ATM mon point de vue sur EF est: "Il est fait pour de très petits systèmes à très petits bits avec pas plus de 3 tables avec moins de 1 relation (0 est mieux)".

Et pourquoi est-ce que je pense comme ça? 1. Essayez de mettre à jour un graphique déconnecté et de voir votre modèle rayé;

  1. Essayez de créer TPH avec des arbres hérités profonds et vous constaterez que vous êtes enfermé dans une seule hiérarchie ou le système se cassera.

  2. Essayez de faire des requêtes plus lourdes et regardez tout le système dévorer la pile: D ... les débordements se produisent très souvent.

  3. Les types de données Map XML sont basés sur des extensions ou sur les propriétés NotMapped les plus "détestées" ... et c'est encore pire.

  4. Essayez de mélanger la requête SQL dans Linq pour des requêtes plus fines et vous briserez le mur lol.

  5. Et la dernière chose et la plus importante, EF ne prend pas en charge la formule de propriété (`` une ressource impressionnante que NH a pour les bases de données héritées ''), et ne prend pas en charge les mappages de types complexes pour la même table et les tables associées.

C'est mon 10cc.

Moisés Gonçalves
la source