.net entity-framework .net-4.0 ado.net

Voto del marco de la entidad sin confianza: ¿relevante en.NET 4?



entity-framework .net-4.0 (4)

Estoy decidiendo sobre un ORM para un gran proyecto y estaba decidido a utilizar ADO.NET Entity Framework, específicamente su nueva versión que se incluye con .NET 4. Durante mi búsqueda de información sobre EF, tropecé con ADO .NET Entity Framework Vote de Sin Confianza, que no estoy seguro de cómo tomar.

El Voto de no confianza se escribió en algún momento de 2008 para convencer a Microsoft de que escuchara críticas específicas por EF v1.

No está claro si las afirmaciones hechas en el Voto de no confianza siguen siendo válidas (en .NET 4) y si son suficientemente serias como para usar otras soluciones. NHibernate es una alternativa madura, pero no sé qué problemas trae. En general, estoy más inclinado a una solución Ms, principalmente porque puedo contar con la integración con VS y con su soporte para desarrolladores.

Agradecería ejemplos de cómo los problemas mencionados en el Voto de No Confianza afectan en proyectos del mundo real. Más importante aún, ¿los reclamos realizados allí siguen siendo relevantes en EF para .NET 4?


Entity Framework ha mejorado desde la versión 1 y esta entrada de blog de un colaborador de NHibernate compara NHibernate y Entity Framework 4.0.



EDITAR: ESTO SE UTILIZA PARA SER VERDADERO, PERO NO ES MÁS.

Como persona que ha usado Entity Framework y NHibernate ... sugiero fuertemente NHibernate. Normalmente, si hay una tecnología de FOSS y MS, sugiero la tecnología de MS, pero estoy totalmente en desacuerdo con eso para EF. Uso EF4 día a día en el trabajo, y tenemos que crear muchas soluciones debido a EF. Hace dos años utilicé EF durante aproximadamente un año, y luego cambié de compañía, y he estado trabajando con EF durante el año pasado. NHibernate, hace 2 años, está por delante de EF4.

Aquí están los puntos que mencionaron.

Conflictos de combinación excesiva con control de código fuente en entornos de equipo:

Esto fue parcialmente arreglado, por lo que escuché. Movieron los datos de posición para el diseñador al final de .edmx, por lo que ya no es un problema horrible, pero sigue siendo molesto. Si yo y un compañero de trabajo intentamos modificar el .edmx al mismo tiempo, tendemos a tener conflictos de fusión horribles porque todo el fondo del archivo se usa para almacenar los datos de posición de las tablas en el diseñador. Nuestra solución a este problema es utilizar el bloqueo de archivos SVN para que no lo editemos en doble. O ignoro el bloqueo, y si tengo un conflicto de fusión, solo acepto sus cambios y vuelvo a hacer mi trabajo. La mayoría de mis cambios no son tan grandes que demoran mucho en volver a realizarse. Si este fuera el único problema, viviría con eso.

Si usa código primero (en EF 4.1) esto no es un problema.

Código de exceso necesario para ocuparse de la falta de carga lenta:

Agregaron carga diferida en 4.0.

Pero está cargando preformas como una basura. La carga ansiosa es lenta, lo cual es una optimización común cuando necesita acelerar su código. Me estoy encontrando con casos en los que tengo que hacer más de 10k llamadas a la base de datos cuando prefiero usar una carga ansiosa. Lo hemos programado y, en muchos casos, es más rápido realizar múltiples llamadas a la base de datos (haciendo myobject.TablenameReference.Load() en un bucle) a una base de datos local y luego usar .Include("Tablename") . Sí, sé que es muy contradictorio, pero los números no mienten. Además, no hay forma de especificar la estrategia de obtención, por lo que no puede especificar la opción de capturar o no. Entonces diría que ha mejorado, pero no tanto como NHibernate.

El enfoque desordenado en el aspecto de los datos de las entidades conduce a arquitecturas de entidades degradadas:

Sí, esto sigue siendo cierto. De nuevo, un buen ejemplo es order.Status. Realmente nos gustaría que fuera una enumeración, pero debido a la forma en que se diseñó EF, no tenemos otra opción además de convertirla en una cadena. Pueden arreglar el problema enumerado en el futuro, pero la falta real de control entre la forma en que se realiza el mapeo entre la mesa y el objeto es la verdadera queja. NHibernate le permite especificar métodos para hacer asignaciones, para manejar este caso.

Para ampliar un punto de la respuesta de Craig Stuntz, EF está diseñado si desea tomar el modelo de datos y seleccionarlo directamente. (IE myModel.Orders.Where(order => order.Status == "NEW").Select(order => order.Customer.FirstName, order=> order.Customer.LastName) .) El modelo de EF termina siendo realmente difícil para escribir pruebas automatizadas si no quieres golpear el DB. Si quieres un repositorio, donde pides un objeto que cumpla con ciertos criterios y devuelve el objeto completo, NHibernate funciona mejor. (IE var order = myOrderRepository.GetByStatus(OrderStatus.New) ).

Otro problema que tengo con EF es su falta total de extensibilidad. Un problema que tenemos es que tenemos Enums para el estado del pedido. Pero si hacemos myModel.Orders.Where(order => order.Status == OrderStatus.New.ToString()) , EF se bloqueará en esa consulta porque no conoce el método .ToString (). Refleja mucho nuestro código porque no podemos agregar soporte para eso. También hay muchos métodos internos, por lo que debemos provocar que ocurra un comportamiento extraño, no podemos hacer eso.

Si está utilizando NHibernate, Linq agrega muchas funciones para nhibernate que lo hacen mucho mejor. Usando un modelo basado en convenciones, requiere muy poco código para la mayoría de sus asignaciones. Si está utilizando una base de datos existente, Nhibernate le permite especificar convenciones no estándar para usar, y luego hacer que se organicen mapas, y todo se administra fácilmente. EF 4.0 (y no creo que 4.1) no tiene soporte para nada de eso.

Espero que esto te ayude.


Siempre he pensado que gran parte de lo que subyace al "voto de censura" era un intento de utilizar el EF como si fuera un clon de NHibernate. No lo es, e incluso en EF 4 intentar usar el EF como si fuera una imitación de NHibernate probablemente terminará en fracaso, aunque es posible que llegue un poco más lejos antes de fallar. Como ejemplo trivial, la mayoría de las personas usa LINQ en NHibernate de forma mínima, si es que lo hace, mientras que no creo que pueda ser productivo en EF a menos que use LINQ bastante.

Por otro lado, he tenido bastante éxito en el uso de EF 1 en sus propios términos, y he logrado no permitir reclamos que la gente hace en publicaciones de blogs para impedir que funcione. Estoy ansioso por utilizar muchas de las nuevas funciones en EF 4, pero me encantaría trabajar en un proyecto EF 1 bien estructurado en cualquier momento. (Para el caso, estoy feliz de trabajar con NHibernate también, y no lo criticaría por no actuar como EF).

Así que estoy tratando de sugerir, de una manera algo delicada, que antes de que pueda decidir si "los reclamos hechos en el Voto de No Confianza siguen siendo válidos (en .NET 4) ..." primero debe decidir si esos reclamos fueron válidos para ti y la forma en que trabajas. Si su comprensión personal de O / R está cableada a NHibernate, EF 4 probablemente todavía le parecerá de segunda categoría. Si, por otro lado, estás dispuesto a aprender la forma de trabajar de EF, entonces probablemente incluso EF 1 parecerá mejor de lo que escuchaste.

Para abordar las afirmaciones de "no confianza" directamente, y examinar tanto su sustancia como lo que ha cambiado en EF 4:

EL ENFOQUE INORDINADO EL ASPECTO DE DATOS DE LAS ENTIDADES CONDUCE A LAS ARQUITECTURAS DE LA ENTIDAD DEGRADA:

Esto es un malentendido del modelo de datos de entidad de Entity Framework. (O, una diferencia de opinión, si lo prefiere). Pero de cualquier manera, es una característica, no un error. Entity Framework está diseñado en torno al caso más general de servicios de datos, no solo a los modelos O / R en particular. Poner comportamientos en entidades devueltas desde un servicio de datos conduce a un desastre al estilo de CORBA. A diferencia de los ORM donde, hasta cierto punto, está atascado con cualquier tipo que salga de la caja negra de ORM, con el modelo de Entity Framework que se espera que proyecte en tipos de negocios. En este caso, los tipos de entidades mapeadas nunca se materializarán.

Esta es una diferencia sustantiva entre el modelo de Entity Framework y muchos otros ORM. Personalmente, considero que separar los comportamientos comerciales del mapeo O / R es bastante más limpio que agruparlos. No tiene que estar de acuerdo con esta idea, pero es claramente una decisión de diseño, no un descuido.

EXCESO DE CÓDIGO NECESARIO PARA TRATAR DE LA FALTA DE CARGA PERJUDICIAL:

El EF 4, para bien o para mal, tiene una carga floja.

Digo "para bien o para mal" porque la carga diferida hace que sea muy fácil generar consultas de bases de datos en exceso. Funciona bien siempre que vigiles de cerca lo que sucede debajo del capó, pero la mayoría de la gente no lo hace. Considero que la projection es una mejor alternativa a la carga diferida, la carga ansiosa o la carga explícita la mayor parte del tiempo.

Aún así, hay momentos en que la carga lenta es conveniente. Así que me complace ver que se agrega en EF 4.

SHARED, CANONICAL MODEL CONTRADICTS SOFTWARE MEJORES PRÁCTICAS:

Es difícil saber qué hacer con esto, ya que algunos de los textos de apoyo no son ni siquiera coherentes en inglés, por ejemplo:

El enfoque del modelo canónico propenso a fallas no fue difícil por la falta de herramientas elaboradas en la línea del Marco de la Entidad.

Esta sección parece sugerir que el Marco de la Entidad impone algún tipo de requisito, o al menos un fuerte sesgo, hacia el uso de un único modelo de datos canónicos para un sistema complejo. No estoy seguro de estar de acuerdo, pero es difícil de decir, dada la falta de un ejemplo específico en esta sección. Así que le diré mis propios sesgos sobre el tema, y ​​puede estar de acuerdo o en desacuerdo conmigo:

A menudo es un error usar un solo modelo para un sistema grande, dependiendo de qué tan grande sea realmente el sistema. Sin embargo, nada en Entity Framework requiere que uses un solo modelo. Por otro lado, Entity Framework, especialmente en la versión 1, no se desvive por hacer que sea más fácil combinar múltiples modelos.

Ahora, una sola y gran aplicación para un sistema complejo puede ser un error tan grande como un solo modelo de datos grandes. Por lo tanto, no sería correcto para Entity Framework facilitar la combinación de muchos modelos pequeños en una aplicación demasiado grande; eso simplemente reemplazaría un problema por otro.

Por otro lado, creo que tiene sentido hacer que sea fácil construir un gran sistema de servicios dividido de una manera que se adapte al dominio del problema. Creo que los servicios de datos de WCF, una tecnología separada del Entity Framework, pero que soporta muy bien el Entity Framework, son útiles para esto.

Creo que el Entity Framework podría, en una versión futura, facilitar la combinación de dos o tres modelos en una sola aplicación cuando sea necesario. Puedes hacer esto ahora, pero hay algún trabajo manual involucrado. Pero como dije antes, no me gustaría "arreglar" un problema de un modelo de datos demasiado grande al facilitar / alentar la creación de una aplicación demasiado grande.

LA FALTA DE IGNORANCIA DE PERSISTENCIA CAUSA QUE LA LÓGICA EMPRESARIAL ES MÁS DIFÍCIL DE LEER, ESCRIBIR Y MODIFICAR, CAUSANDO QUE LOS COSTOS DE DESARROLLO Y DE MANTENIMIENTO SE INCREMENTAN A UNA TASA EXAGERADA:

Esta sección hace afirmaciones que considero erróneas:

Entity Framework alienta el patrón anti-patrón Anemic al desalentar la inclusión de la lógica comercial en las clases de entidades.

Véase más arriba. Creo que el trabajo de los tipos de entidades es hacer un mapa entre el espacio relacional en el espacio objeto. Según el Principio de Responsabilidad Individual, estos tipos solo deberían modificarse cuando cambie su único trabajo. Si los procesos empresariales cambian, esta es una responsabilidad no relacionada con la asignación O / R. Quizás las limitaciones de otros ORM imponen una barrera técnica para separar estas responsabilidades. Está bien doblar las reglas cuando la tecnología lo dicta, si el costo de la pureza del diseño es excesivo. Pero estoy muy a favor del enfoque de tipos de entidades sin comportamiento.

En su estado actual, las clases de entidad EF no pueden ser probadas de manera efectiva independientemente de la base de datos.

Esto es simplemente incorrecto Quien escribió esto no entendió de qué estaban hablando. Ninguna de nuestras pruebas unitarias toca el DB, nunca, y muchas involucran el EF.

En lo que respecta al contenido del título de esta sección, hay un cambio para EF 4. Ahora es posible tener tipos de entidades completamente ignorantes de la persistencia, si eso ayuda a su diseño. Sin embargo, desde la versión más antigua del Entity Framework en palabras, ha podido proyectar en POCO. Así que la ignorancia de la persistencia siempre ha estado disponible cuando se requiere. Tener ignorancia de persistencia en los propios tipos de entidades permite el seguimiento de cambios con un objeto que ignora la persistencia. Eso puede ser útil en algunos casos. Pero es un subconjunto de casos sustancialmente más pequeño que las afirmaciones falsas sobre pruebas unitarias, lo que disminuye mucho el impacto del punto que el documento hace.

CONFLICTOS DE FUSIÓN EXCESIVA CON CONTROL DE FUENTE EN ENTORNOS DE EQUIPO:

¿La combinación de XML realmente es tan difícil? Si es así, quizás uno debería buscar una nueva herramienta de combinación. No encuentro esto problemático.

Sin embargo, aquí hay un problema real, aunque, una vez más, es mucho más limitado de lo que afirma el documento. En lugar de repetirme, solo te señalaré mi publicación sobre ese tema .

En EF 4, uno puede usar modelos de primer código en lugar de modelos XML para dividir un modelo en muchos archivos diferentes.