Entity Framework 4 vs NHibernate

Mucho se ha hablado sobre la primera versión de Entity Framework en la web (también en stackoverflow) y está claro que no era una buena opción cuando ya tenemos una mejor alternativa como NHibernate. Pero no puedo encontrar una buena comparación de Entity Framework 4 y NHibernate. Podemos decir que hoy NHibernate es el líder entre todos los .NET ORM, pero podemos esperar que Entity Framework 4 desplace a NHibernate de esta posición. Creo que si Microsoft realmente ha inyectado funciones muy buenas en EF4, puede ofrecer una buena competencia a NHibernate, ya que tiene integración con Visual Studio, es más fácil trabajar con ella y siempre se da preferencia a los productos de MS en la mayoría de las tiendas.

EF4 tiene una respuesta lista para usar con respecto al desarrollo de n niveles, en “entidades de auto-seguimiento”. Nadie ha publicado un código comparable para NHib.

NHib tiene muchas características que no se han mencionado como parte de EF4. Estos incluyen la integración de caché de segundo nivel. También tiene una mayor flexibilidad en el mapeo de herencia, una mejor integración con funciones almacenadas de bases de datos / procuración / SQL / desencadenantes personalizados, soporte para propiedades de fórmulas, etc. OMI básicamente es más maduro como ORM.

Actualización: no he usado Entity Framework desde la versión 4.0, por lo que mi respuesta puede estar desactualizada. Todavía estoy usando NH o ADO .NET puro en mis proyectos. Y ni siquiera quiero ver qué hay de nuevo en EF desde 4.0, porque NH funciona perfectamente.

En realidad, es bastante fácil compararlos cuando has usado ambos. Hay algunas limitaciones serias con EF4, puedo nombrar algunas que encontré por mi cuenta:

Problemas de EF4:

  • Eager Cargando y dando forma al resultado : EF4 El sistema de carga ansioso (Include (“Path”)) genera SQL incorrecto, con JOIN de bucle, que ejecutará miles (no literalmente) tiempo más lento para las relaciones de muchos a muchos y SQL escrito a mano (es efectivamente inutilizable).
  • El materializador no puede materializar las entidades asociadas : si puede pensar que puede superar el problema anterior proporcionando su propia consulta SQL, está equivocado. EF4 no puede materializar (mapear) entidades asociadas desde la consulta JOIN SQL, solo puede cargar datos de una tabla (Entonces, si tiene Order.Product, SELECT * FROM order LEFT JOIN El producto inicializará solo el objeto Order, Product permanecerá nulo, pensé que todos los datos necesarios se obtienen en la consulta para iniciarlo). Esto se puede superar utilizando el complemento de la comunidad EFExtensions, pero el código que tendrá que escribir para esto es realmente feo (lo intenté).
  • Entidades de seguimiento automático : muchos dicen que las entidades de seguimiento automático son geniales para el desarrollo de N niveles, incluida la respuesta principal en este hilo. Pensé que ni siquiera los había probado, puedo decir que no. Se pueden falsificar todos los datos, no se puede simplemente tomar los cambios que el usuario le envía y aplicarlos a la base de datos, ¿por qué no darle al usuario datos directos? acceso base, entonces? Cualquier forma en que tenga que cargar el usuario de datos está a punto de cambiar de DB, compruebe que exista | no existe, haga comprobaciones de permisos, etc. No puede confiar en el usuario sobre el estado de la entidad que está enviando al servidor, de todos modos tiene que cargar esta entidad de DB y determinar su estado y otras cosas, por lo que esta información es inútil, al igual que las entidades de auto-seguimiento a menos que haga un sistema de n niveles privado confiable para uso interno, en cuyo caso tal vez podría dar simplemente Acceso DB (Eso es lo que pienso sobre las Entidades ST y N-tire, no tengo mucha experiencia en N-Tier, así que puede cambiar, si malinterpreté algo aquí, coméntelo)

  • Registro, eventos, integración de la lógica de negocios: EF4 es como una caja negra, hace algo y no tiene idea de lo que hace. Solo hay un evento OnSavingChanges en el que puede poner alguna lógica de negocios que necesite ejecutar antes de que algo suceda con DB, y si necesita aplicar algunos cambios a objetos de negocios antes de que ocurra algo, tendrá que cavar en ObjectStateManager, y esto es realmente feo , el código puede volverse enorme Si, por ejemplo, usa el patrón Repositorio y lo que debe notificarse sobre los cambios realizados en el DB en forma de objeto limpio, tendrá dificultades para hacerlo con EF.

  • Extensibilidad: todo el código EF es privado e interno, si no te gusta algo (y no te gustará MUCHO si tomas en serio el uso de EF), no hay forma de que lo cambies de manera fácil, de hecho estoy seguro es más fácil escribir tu propio ORM desde cero (lo hice) y luego hacer que EF funcione como lo necesitas. Como ejemplo, echa un vistazo a la fuente EFExtensions, está basada en métodos de extensiones y diferentes “hacks” para hacer que EF sea más útil, y el código es bastante feo (y no es culpa de los autores, cuando todo en EF es privado, este es el único forma de extenderlo).

Puedo continuar escribiendo cosas malas sobre EF y lo doloroso que fue para mí trabajar con él por 20 páginas, y tal vez lo haga.

¿Qué hay de NHibernate? Es un nivel completamente diferente, es como comparar PHP con C #, EF4 es como en Stone-age, es como que EF está 10 años atrás de NHibernate en el progreso del desarrollo, y de hecho lo es, Hibernate se inició en 2001. Si tienes tiempo libre para aprender y activar Nhibernate, hazlo.

Aquí está la cosa. NHibernate y Entity Framework son realmente para dos audiencias diferentes, en mi opinión. NHibernate sería mi elección para construir un sistema con mapeos complejos, fórmulas y restricciones (básicamente, cualquier cosa empresarial). Si quisiera lanzarme al terreno con acceso a datos simple, usaría Entity Framework o LINQ-to-SQL. NHibernate no tiene una experiencia clara de “arrastrar y soltar” como EF. Ambos tienen sus fortalezas y desventajas. Comparando manzanas con manzanas, francamente, no te lleva a ninguna parte.

Si crees que alguna vez querrás ejecutar tu código en Mono, NHibernate es probablemente una mejor opción sin importar lo que digan las listas de verificación de funciones …

Editar, 13/8/2012:

Entity Framework ha sido de código abierto, y ahora está incluido en Mono a partir de 2.11.3. Esta respuesta ahora está desactualizada y no se debe confiar en ella.

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

Mi opinión sobre esto es que EF4.0 ha recorrido un largo camino desde 1.0 y está alcanzando a Nhibernate en funcionalidad, pero aún no está todo allí.

Sin embargo, es Microsoft, listo para usar, y hace el 100% de lo que el 95% de las aplicaciones necesitan. Sin embargo, NHibernate ha estado haciendo lo mismo durante años. Venga versión 5.0 o 6.0 puede ponerse al día, o incluso superar NHibernate.

Aquí está mi consejo: si tienes tiempo para aprender ambas cosas, hazlo. Hay varias razones para elegir una sobre la otra. Si está escribiendo código para una corporación, es realista esperar que los empleados que estén familiarizados con EF, ya que está en todos los libros y lo que los niños aprenden en la universidad. Si EF cumple con sus requisitos (piense en esto larga y duramente antes de decir que sí), entonces es una solución perfectamente perfecta por ahora, y en unos pocos años puede (vale, lo más probable) superar a NHibernate.

NHibernate es un producto muy maduro con algunos años en EF y probablemente hará todo lo que siempre desearía hacer y más. Ha sido el mejor ORM desde hace un tiempo y mucha gente lo usa.

Creo que el hecho de que EF 4 tenga la capacidad de usar POCO y la carga diferida diferida será muy grande. Definitivamente podría verlo ganar tracción con el nuevo lanzamiento.

Existe una tendencia obvia de boost la popularidad de EF sobre NHibernate, ver la imagen.

NHibernate vs Entity Framework

Mis 2 centavos: utilizamos ef en nuestro cliente de escritorio para algo de cahing, etc., sin cargas. Un NHib en el lado del servidor: utiliza sesiones sin estado, generación de id de hilo y lotes. Es bastante rápido al insertar 3k + mensajes en db por segundo. También es muy flexible y admite muchos dbs, lo cual es crucial para nuestro producto.

Asignar directamente a los procedimientos almacenados con una combinación de Linq para una capa lógica parece el enfoque más fácil. No xml Genere sql solo para consultas interesantes que se usan con menos frecuencia o no son adecuadas para procedimientos almacenados.

Los objetos cargan y almacenan a través de SP estándar. Este enfoque permite el uso de dos inicios de sesión sql. Uno para el acceso de clase a través de SP (permisos de solo ejecución) y otro para un módulo de lógica lógica que permite el acceso directo a la tabla.

Elegir entre ORM por popularidad no es lo mejor que puedes hacer. Intenté pasar a EF en los últimos 2 años y todo lo que puedo decir es, ¿por qué diablos sigo intentándolo?

ATM: mi punto de vista sobre EF es: “Está hecho para sistemas muy pequeños y pequeños, con no más de 3 tablas con menos de 1 relación (0 es mejor)”.

¿Y por qué pienso así? 1. Intente actualizar un gráfico desconectado y vea el rasguño de su modelo;

  1. Trate de hacer TPH con árboles heredados profundos y encontrará que está pegado a una sola jerarquía o que el sistema se romperá.

  2. Intente hacer consultas más engorrosas y observe cómo todo el sistema consume la stack: D … los desbordes ocurren muy a menudo.

  3. Los tipos de datos Map Map XML se basan en extensiones o las propiedades NotMapped más “detestadas” … y es aún peor.

  4. Intenta mezclar consulta SQL en Linq para obtener más consultas finner y romperás el muro jajaja.

  5. Y lo último y más importante, EF no es compatible con la fórmula de propiedad (‘un recursos increíbles que NH tiene para bases de datos heredadas’), y no admite mapeos de tipos complejos para la misma tabla y tablas relacionadas.

Esa es mi 10cc.