para - Capa de acceso a datos ORM vs Handcoded
orm para c# (16)
Tengo un poco de miedo para hacer esta pregunta, ya que puede comenzar una guerra religiosa, así que quiero ser muy claro sobre lo que estoy buscando. Estoy buscando una (s) razón (es) por la (s) razón (es) por la (s) cual (es) o (s) me han brincado de una forma u otra y también por artículos para agregar a mis listas. Estoy buscando el boleto grande, artículos de Big Bang. Además, los artículos específicos de un producto, tal vez, si son realmente relevantes. En este punto estoy tratando de evaluar ORM vs Manual no producto A versus producto B.
Ventajas de ORM
- Quick to code and low maintenance (in some/most scenarios) - Additional features for "free" (no developer effort)
Ventajas codificadas a mano
- More Efficient (at runtime, maybe not at dev time?) - Less layers of complexity - Most ORMS seem to struggle with being retricted to sprocs only
En aras de una divulgación completa, realmente no me gusta la idea de "algo" ejecutar código en mi base de datos que no puedo modificar directamente, si lo veo correcto, pero puedo ver las ventajas de tiempo de desarrollo potencialmente masivas de un ORM.
También es probable que valga la pena señalar que estoy en un mundo .Net
[edit] (la pregunta en Using an ORM or plain SQL? parece responder muchas de las preguntas y refuerza el punto sobre el rendimiento)
Entonces, para alterar mi pregunta ligeramente
¿Alguna vez ha construido una aplicación usando un ORM en las primeras etapas y luego la reemplaza gradualmente con un DAL codificado a mano? ¿Cuáles fueron los peligros de este enfoque?
[Editar más - llegar al corazón del problema ahora] Tener un sitio web para poder ejecutar cualquier SQL en mi base de datos es aterrador. Si todo el acceso es a través de sprocs mi base de datos vive en un aislamiento agradable, seguro y cómodo. El uso exclusivo de sprocs elimina una gran cantidad de, si no todos, los vectores de ataque de inyección SQL. ¿Algún comentario sobre eso?
¿Has probado redbean? En fase de desarrollo, es fluido y fácil de usar, mientras que en modo de producción (congelado) es rápido. http://redbeanphp.com
Comenta en tu pregunta sobre el procedimiento almacenado. No importa cómo se escribe la funcionalidad, DAL, ORM, procs almacenados, habrá SQL involucrado. Si usa procedimientos almacenados, escribe el SQL en el interior y es relativamente fácil crear abstracciones útiles. Si usa DAL, escribe el SQL, pero en la práctica es más probable que sea SQL no absorbido con una mayor exposición a la inyección. Si usa ORM, la herramienta escribe el SQL (del que, no obstante, usted es el único responsable, incluida la inyectabilidad). En mi humilde opinión, la menor cantidad de partes móviles (especialmente las que conoces y entiendes) mejor.
De acuerdo, esto fue para una aplicación PHP, no para .net, pero creo que las mismas cualidades son importantes.
Recientemente reescribí una aplicación de intranet de PHP que estaba basada en bases de datos. Como es típico de muchas aplicaciones de PHP que "han crecido", no utilizaban ningún tipo de ORM y tenían un montón de código duplicado, la mayoría de las cuales generaba consultas similares de diferentes maneras.
Tuve una visión superficial de algunos marcos ORM, pero todos tenían un gran problema: habrían requerido personalización para trabajar en nuestra estructura. El gran componente que faltaba era la escalabilidad de la base de datos. Así que escribí mi propio controlador. Luego, era una simple cuestión continuar y construir nuestra propia capa de datos basada en objetos. Implementamos funciones que queríamos, que hicieran lo que necesitábamos.
En retrospectiva, este fue un ejercicio enormemente útil para mí. Significa que ahora sé cómo funcionan las capas ORM y cómo deben funcionar. También se oponía a la tendencia de una gran cantidad de escala de la base de datos, ya que planteó el problema en la aplicación, donde el conocimiento sobre los datos era.
Hace unas semanas comencé a desarrollar un nuevo proyecto. Tenía control total sobre las herramientas que podía usar. Empecé con db40 porque quería eliminar esta pregunta por completo; Solo quería persistir mis objetos directamente, olvidarse de ADO.NET u OR / M. Pero db40 tenía problemas, así que tuve que abandonarlo.
Mi siguiente elección fue ADO.NET porque pensé que sería rápido y fácil. Pero tuve que escribir demasiados códigos, usar demasiado "string sql" y era solo una tarea completa. Quiero decir, era un PITA real y después de codificar dos repositorios con él, quería cortarme las muñecas.
Mi tercera opción fue NHibernate. He tenido problemas previos con NHibernate en una situación en la que necesitaba usar objetos desconectados (este también fue el caso esta vez, de ahí que me costó tres intentos llegar a él). Pero eso fue NHibernate 1.2. Esta vez obtuve los binarios 2.0 y no tuve problemas para actualizar los objetos desconectados. También tuve que escribir muchas menos líneas de código y fue súper simple cuando necesité refactorizar las cosas, que probablemente fue lo más importante ya que mi diseño cambió rápidamente.
Estoy vendido en NHibernate ahora. Parece altamente optimizado también. Honestamente, no puedo encontrarle una respuesta negativa. Y no hay procedimientos almacenados.
Sé que es mi OR / M de elección en el futuro y nunca escribiré ADO.NET de nuevo.
He luchado con esto por algunos años. Miró muchas cosas. Y durante los últimos 3 meses me he dado cuenta "por qué estoy perdiendo todo este tiempo en esto". Como que veo el ORM como un problema resuelto. Preferiría confiar en algún equipo que tiene un enfoque completo en ORM para escribir una capa de ORM que yo. Mentalmente, estoy listo para nuevos desafíos.
Mi elección es NHibernate. Realmente soy nuevo en esto ahora mismo. Pero me gusta el potencial de usar Fluent NHibernate o Castle ACtiveRecord también. Esto parece ser donde está la mente compartida.
Pero no estoy seguro de qué haría en un mundo de "todo es un fracaso".
He tenido mucho éxito simplemente usando un DataSets en .Net. Tenemos un punto final SOAP que primero validará la entrada con un .XSD. Luego, puede usar un motor de reglas para hacer alguna validación. Entonces...
Si la solicitud es para insertar datos:
- Use GetXml () en el DataSet para convertir a XML.
- Envíe el XML a un sproc que use OPENXML en SQL Server.
Si la solicitud es para seleccionar datos:
- Escriba un sproc para escupir los datos con múltiples instrucciones SELECT.
- Cargue esos datos en un DataSet (asegurándose de construir relaciones "anidadas" donde sea necesario).
- Use GetXml () en DataSet para convertir a XML utilizado en SOAP.
He utilizado este proceso con mucho éxito en varios entornos de producción. Es rápido y sencillo si sabes que solo usarás SQL Server.
He usado Subsonic para un par de proyectos grandes. No estoy abogando por el uso de un ORM sobre otro, pero no haría otro proyecto relacionado con la base de datos sin uno. La capacidad de regenerar toda la capa de acceso db cada vez que cambio la estructura de la base de datos, la capacidad de agregar características en un lugar que afectan a toda la capa de DB.
La cuestión es que debe comprender cómo interactúa con la base de datos, de lo contrario correrá el riesgo de escribir (severamente) un código de bajo rendimiento. Su herramienta ORM puede proporcionarle una buena vista orientada a objetos de sus datos, pero es posible que encuentre que está transmitiendo tablas completas al cliente para hacer un procesamiento simple. La base de datos es buena para relacionar y filtrar datos, así que asegúrese de que todavía tenga ese trabajo. Irónicamente, la falta de uniones de Subsonic (en la versión que utilicé) me ayudó con eso, porque me forzó a crear Vistas de BD para combinar datos donde fuera necesario.
Un amigo mío trabajó con un chico que desarrolló una herramienta ORM interna. Tenía la bonita función de almacenar en caché localmente todo lo que pudieras desear de la base de datos, al recorrer las claves externas. La desventaja fue que al leer una columna de una fila en el DB resultó en un exceso de 11,000 declaraciones seleccionadas.
Heredé una aplicación web que se creó con NHib y MyGeneration, desafortunadamente no obtuve el repositorio svn, y ya no tengo las plantillas iniciales (arrggg).
Haber guardado nhibernate para Crear / Actualizar / Eliminar cosas de la parte de atrás, pero el front-end (solo lectura) se ha implementado de forma poco ingeniosa, y se ejecuta como un perro de dos patas, y ahora se reescribe en el viejo ADO.NET antiguo, y sube hasta 10 veces más rápido.
No estoy diciendo que esto se deba a NHibernate, es debido a que los desarrolladores no saben cuánta porquería están enviando a lo largo del cable, y asumiendo que usar ciegamente una herramienta significaría que no tenían que pensar en ello.
A los efectos de las consultas de solo lectura, a menudo puede hacer que sean mucho más eficientes escribiéndolo a mano.
Para cosas que tienen que escribir en el DB, generalmente es más fácil, y no mucho más lento, dejar que un ORM decente lo haga.
Mi preferencia personal es SubSonic, que he encontrado funciona bastante bien para proyectos de tamaño mediano, y si encuentra un cuello de botella, puede solucionarlo a mano.
Las herramientas son geniales, y cualquier cosa que me dé más fines de semana es doblemente grande, pero no hay sustituto para la herramienta entre tus oídos.
Los procesos almacenados no eliminan el riesgo de inyección sql. Es probable que la persona que probablemente haga consultas en el código lo haga en un proceso almacenado. Y cualquier buen ORM no hace concats de cuerdas de modo que no hay problema.
No necesita abandonar sus SPROC o SQL hecho a mano con un buen ORM como nHibernate.
He reemplazado mis métodos de acceso a datos ORM después del hecho, no es nada difícil, es lo mejor de ambos mundos.
Tuve que reescribir un DAL de una aplicación de producción que utilizaba una base de datos de objetos. Queríamos admitir las bases de datos DB y SQL de objetos. Algunas características que realmente no quería implementar yo mismo, donde las características presentes ya estaban
- lazyloading transparente con anulaciones de consulta
- Identidad de la entidad (siempre obtener la misma referencia para entidades iguales)
- Insertar / actualizar lotes
- Seleccionar lotes (futuros en NHibernate)
- Generación Id
- traducir la API de consulta a sql (los criterios eran perfectos debido a la naturaleza modular de la API de consulta)
Es por eso que elegí NHibernate como mi ORM con el que estoy contento. Y obtuve algunas características agradables gratis.
- Automatización de clases (en total 3 páginas de código para generar las asignaciones completas)
- Soporte de LINQ (¿Alguna vez intentó implementar el proveedor LINQ por su cuenta?)
- registro extenso gratis
- prueba unitaria más fácil con inmemory sqlite
- soporte para diferentes proveedores de db
- generación de esquema superfácil (no es necesario mantener ningún script de generación para diferentes proveedores de db)
- concurrencia optimista
- documentación para N / Hibernate es un gran recurso de aprendizaje para técnicas relacionales
No me puedo imaginar cómo escribir SQL a mano mejor que lo que NHibernate está generando. Algunos argumentos en contra:
- cargar todo el objeto cuando solo se necesitan pocas propiedades -> siempre hay Projecting en DTOs o en C # 3.0 en tipos anónimos (SetProjection () / Select ())
- muchos selects en lugar de join -> usando la carga ansiosa donde sea necesario (SetFetchMode () / Fetch ())
- el sql ajustado siempre es más eficiente que el generado -> optimización de arquitectura >> optimización de micro, con ORM fue mucho más fácil refactorizar la arquitectura debido a un menor número de códigos y lógica menos repetida (intente cambiar algo así como de uno a muchos a muchos a: muchos en dal manuscrito)
Utilicé la implementación Active Record de Castle Project con NHibernate para un proyecto personal. El proyecto nunca se implementó, en parte debido a mi incapacidad para trabajar con la opción de ORM que hice.
La razón por la que decidí usar ORM fue porque quería la capacidad de cambiar de SQL Server a MYSQL sin cambiar mi código. En proyectos reales, la decisión de utilizar SQL Server ya está hecha para mí, y es más fácil simplemente escribir capas de datos de la manera tradicional de 3 niveles cuando sabes que la base de datos no cambiará. Pero para proyectos personales uso hosting compartido, y MySQL es una solución más barata.
La razón por la que fui con Castle fue porque era muy fácil de usar. Con el plugin activewriter para visual studio, pude generar mis clases y bases de datos usando un diseñador (algo así como el diseñador linq to SQL), y parecía encajar bien con mi modelo mental de cómo el ORM debería dictar la arquitectura de tu aplicación .
El problema que tuve con ese ORM fue que no pude encontrar información sobre cómo optimizarlo correctamente. Estaba haciendo llamadas extremadamente grandes a la base de datos. (La consulta SQL generada para obtener un usuario fue de 1mb de texto cuando lo logré).
Entonces, usando el ORM, me ahorré mucho trabajo por adelantado, pero me topé con una pared cuando traté de solucionar el problema con el framework que generaba demasiado SQL. (Sobre el cual todavía estoy trabajando lentamente).
Aunque no encontré la solución perfecta, todavía intentaría ORM para otros proyectos personales, porque soy solo yo y quiero dedicar el tiempo de mi proyecto al código divertido, no a las capas de datos.
En el trabajo, sin embargo, probablemente no me apresuraría a sugerir que utilizáramos un ORM antes de ser un experto (tal vez después de tener varios proyectos personales que trabajan a mis espaldas).
Yo diría que los ORM solo son "rápidos de codificar" desde el principio, especialmente si no tiene un esquema instalado existente. Una vez que necesite comenzar a exprimir más rendimiento de su sistema, necesitará un ORM que pueda ser "desechado rápidamente".
Encuentro que son una lata de gusanos.
buena pregunta y buenas respuestas. Me he involucrado con estos temas también. Prefiero un ORM como SubSonic a DAL codificado a mano.
He estado escribiendo y manteniendo mi propio ORM durante 8 años. Comenzó en Java, luego se tradujo en C #. No puedo imaginar escribir ningún sistema respaldado por la base de datos sin él. Es mucho más simple que NHibernate, y no tiene todas sus características, pero hace el trabajo y es bastante rápido, aunque utiliza la reflexión de manera exhaustiva, ya que reemplaza la configuración XML con la reflexión sobre las definiciones de clase DAO.
Estoy bastante contento con eso, y no usaría ningún otro enfoque.
EDITAR: con respecto a los ataques de inyección SQL: un sistema reciente que desarrollé usando este ORM fue ampliamente auditado y no se permitió ninguna inyección. La razón es simple: genera SQL sobre la marcha y siempre usa parámetros, sin concatenación de cadenas.
Inicialmente, escribimos una aplicación con JPA desde el día en que entró en producción, lo hemos lamentado. La cantidad de llamadas a la base de datos realizadas por el ORM fue astronómica, por lo que ahora hemos comenzado el proceso de reescribir la aplicación a máquina utilizando el buen JDBC antiguo utilizando las clases de ayuda JDBC de Spring. Las dificultades de comenzar con un ORM es que pasamos mucho tiempo aprendiendo JPA y al final del día tenemos que reemplazarlo con JDBC para que nuestra aplicación pueda ser más escalable sin agregar otros 3 nodos a nuestro Oracle RAC. Entonces, si lo equilibras, el control y la precisión de JDBC valieron las líneas adicionales de código que tienes que escribir. Además, la mayoría de las personas no entienden que SQL no es algo que se puede generar y esperar que se realice. Es algo que debe escribirse y modificarse para obtener el máximo rendimiento.