.net - net - datatable c#
ORM de cosecha propia vs. DataTables? (8)
Esto es una simplificación del problema (hay muchas formas de hacer las cosas), pero entre las aplicaciones que necesitan hablar con una base de datos usualmente he visto uno de dos patrones:
- Asignación relacional de objetos (ORM), donde (normalmente) cada tabla en la base de datos tiene una clase correspondiente de "fila contenedora" con propiedades públicas que coinciden con las columnas de la tabla. A veces, estas clases también recuperan automágicamente información relacionada, de modo que las columnas de clave externa pueden mostrarse y mostrarse como los datos relacionados (en lugar de solo los valores PK).
- DataTables (y / o DataSets), donde los datos se recuperan del servidor como DataTable y se trabajan con ese formulario (incluso en la interfaz de usuario).
Una de las principales diferencias entre los dos enfoques es que ORM le permite hacer referencia a los campos fuertemente tipados en su código de esta manera:
Person bob = new Person();
bob.FirstName = "Bob";
collectionPeople.Add(bob);
mientras que con el enfoque DataTable tu código sería algo así como:
DataRow newrow = datatablePeople.NewRow();
newrow["FirstName"] = "Bob";
datatablePeople.Rows.Add(newrow);
En este caso, el enfoque ORM se beneficia de la verificación en tiempo de compilación, mientras que el enfoque de DataTable no. Por otro lado, el DataTable (y el DataSet) son estructuras de datos ya escritas que hacen un excelente trabajo al representar datos relacionales directamente, por lo que el código que los usa se puede implementar más rápidamente. Además, el código que usa DataTables puede ser fácilmente entendido y modificado por otros; los sistemas ORM de cosecha propia (y a menudo COTS) a menudo tienen acceso adicional a la base de datos "debajo del capó" para rellenar claves externas, etc., lo que puede crear problemas para los desconocedores.
Entonces, ¿qué enfoque generalmente favorece y por qué?
Solía usar un lector de datos para leer campos en mi objeto utilizando GetString, GetInt, etc., pero ahora me he movido a un enfoque mucho más orientado a objetos y comprobable utilizando una puerta de enlace para devolver una tabla de datos de una consulta, esto luego se pasa a una clase de servicio que analiza la tabla en un objeto.
Nunca me gustaron las herramientas ORM, siempre eran engorrosas y difíciles de mantener, pero aún no he tenido la oportunidad de jugar con LINQ, así que mi opinión puede cambiar.
Yo prefiero el modo DataTables, porque soy viejo, cansado y escéptico con las modas como Subsonic y Linq.
Más allá de eso, cuando trabajas con un ORM, generalmente estás minimizando lo que haces en SQL. No se pone mucha lógica en el SQL y no se combinan varias sentencias de SQL para hacer varias cosas en un solo viaje a la base de datos. Por lo tanto, tiende a ir a la base de datos con más frecuencia, y eso es un gran golpe de rendimiento.
Usando conjuntos de datos, puedo hacer algo como:
seleccione col1, col2 ... de la tabla1
seleccione col1, col2 ... de table2
seleccione col1, col2 ... de table3
y luego haga UN viaje a la base de datos para obtener los tres DataSets, usando Tablas [0], Tablas [1], Tablas [2] para hacer referencia a ellas. Hace una gran diferencia en el rendimiento.
Algún día, tal vez, la interacción con la base de datos será tan rápida que no tendría sentido combinar el SQL, pero ese día aún no llegó. Cuando llegue, cambiaré a ORM, pero hasta entonces, estoy dispuesto a que mi código sea un poco más feo a cambio de rendimiento. No es divertido para los usuarios usar una aplicación inactiva.
Finalmente, me gusta SQL. Soy bueno en SQL. Muy bueno. No quiero perder el tiempo tratando de encontrar la manera de ayudar a Linq a emitir el SQL que quiero. Disminuiría mi rendimiento.
Datatable será conceptualmente más directo en el trabajo con datos. Y está desprovisto de modismos a veces no naturales que se encuentran en ORM. (consultar un registro en la memoria local, antes de actualizarlo; las uniones son punteros; el valor de la clave en sí es un puntero, por lo tanto, agregar un registro requiere cargar el registro principal)
Las grandes ventajas para ORM son ...
1) escribe el sql para usted, por lo que realmente no tiene que escribir ningún sql para hacer crud básico. Por supuesto, escribir afirmaciones más complejas tiene que hacerse en una sublengua menos poderosa (es decir, hql)
2) La otra gran ventaja de ORM es cuando obtiene resultados, los mapea en objetos de valor, sin escribir un montón de código para mapear los valores y manejar la conversión de tipos.
Si tienes habilidades sólidas de sql pero quieres la ventaja 2 cubierta, iría con ibatis
Me parece que puedo desarrollar menos código y probar mejor mi código usando un ORM que DataSets / DataTables. Actualmente estoy usando LINQ-to-SQL y envolviendo una capa delgada alrededor del código generado por el diseñador a través de clases parciales como mi ORM. La capa delgada básicamente me permite agregar algunos permisos basados en roles y aumenta la capacidad de prueba del código refactorizando las interfaces y usando la inyección de dependencia para especificar el contexto de los datos (de esa manera puedo simularlo para otras pruebas).
He hecho ambas cosas: escribir mi propio ORM alrededor de DS / DT, DS / DT fuertemente tipado, etc., y haber cambiado a LINQ y no voy a volver. Eventualmente puedo pasar a algo como NHibernate, Entity Framework u otra cosa, pero por ahora mi solución LINQ ofrece casi todo lo que necesito y es mucho más simple que mis soluciones anteriores.
Puede combinar ambos enfoques mencionados utilizando Strongly Typed DataSets .
Es posible agregarlos a un proyecto de Visual Studio a través del cuadro de diálogo "Agregar nuevo elemento" "Plantilla de conjunto de datos" y luego usar el Diseñador de Dataset visual (edita el archivo XSD detrás de las escenas).
Hay otro artículo sobre el tema.
En .NET, los conjuntos de datos fuertemente tipados tienen los beneficios que usted atribuye a ORM: el valor de la tipificación fuerte en IDE e Intellisense.
Los TableAdapters creados en Visual Studio escribirán todos sus SQL CRUD por usted. Usted pone su lógica comercial en C # (u otra lengua) y no en el SQL.
Creo que el modelo de datos desconectado que ofrecen los conjuntos de datos demuestra ser más eficiente en la práctica que el típico código codificado a mano. Conduce a interacciones DB no parlanchinas en las que obtienes todos tus datos de tabla relacionados en una sola consulta. Y tiene muy buen soporte para el bloqueo optimista (que proporciona excepciones DBConcurrency). El conjunto de datos también rastrea las inserciones, modificaciones y eliminaciones de sus datos, por lo que no es necesario.
Los conjuntos de datos fuertemente tipados también ofrecen una navegación directa hacia los datos de tablas relacionadas.
Una buena referencia en DataSets es
Programación Microsoft® ADO.NET 2.0 Core Reference por David Sceppa
Editor: Microsoft Press Pub Fecha: 17 de mayo de 2006 Imprimir ISBN-10: 0-7356-2206-X Imprimir ISBN-13: 978-0-7356-2206-7 Páginas: 800
+ tom
Solía usar DataSets en los primeros días de .NET, luego comencé a usar DataSets con tipo, con el tiempo descubrí que la huella de memoria dejada por los DataSets es muy alta y no tenía sentido usar objetos no administrados para cada tarea simple.
Por lo tanto, concluyó que los DTO / POCO son una mejor opción y comenzaron a utilizar NHibernate e iBatis.
Mis desarrolladores promedio (o por debajo del promedio) los encontraron complejos y difíciles de usar (sin juego de palabras).
Así que creé un ORM XmlDataMapper de origen interno que era mucho más fácil de usar que los ORM complejos que existen.
Para integrar XmlDataMapper todo lo que necesita hacer es 4 pequeños pasos
- Crear una Entidad comercial / DTO para las tablas
- Cree un archivo XML con la información de asignación entre la tabla y el DTO.
- Especifique el archivo DTO y xml en la configuración.
- Simplemente llame al DTOConverter.Convert (dataReader) y a otros métodos para convertir su registro de base de datos a DTO / Business Entity
Me gustaría ver las ventajas de los objetos de datos frente a DataTables (una biblioteca de ORM elegante no es realmente necesaria, aunque pueden ser agradables):
- Conceptualmente limpio. Estás obligado a aplicar conceptos OO a tus datos. Es más fácil entender "esta es una persona" frente a "la persona que quiero está en algún lugar de esta tabla".
- Impulsa la separación de preocupaciones. Es tentador introducir los datos de contexto de la interfaz de usuario en una tabla de datos: para una interfaz de usuario, obtengo una persona con una dirección principal en el mismo registro, y para otra, obtengo una persona con información de crédito en el mismo registro. Cuando estoy trabajando con un modelo, quiero que ese modelo sea consistente donde sea que lo consuma.
Transforma los datos solo una vez. En las aplicaciones de trituración de DataTable que he visto, hay una gran cantidad de esto diseminado por todas partes:
if (row ["col"] == DBNull.Value || string.IsNullOrEmpty (row ["col"] como cadena)) ...
Prefiero comprobar esa condición una vez cuando llene el objeto de datos en lugar de comprobarlo en todos los lugares donde se usa DataTable.
- Prueba de unidad más fácil. Si hace referencia a un campo en un objeto de datos que no existe, obtendrá un error en tiempo de compilación. Si hace referencia a un campo en una DataTable que no existe, obtiene un error en tiempo de ejecución.
Yo creo que ORM puede hacerte perezoso. Por ejemplo, no hay absolutamente ninguna razón para completar un conjunto de objetos de datos relacionados a partir de consultas individuales en los objetos si esos objetos siempre se usan juntos. En su lugar, escriba una consulta grande y eficiente que capture todos los datos necesarios y luego construya el gráfico del objeto de datos. Aún así, si mantiene sus limitaciones en mente, ahorra mucho trabajo.
Relacionado: Cómo convencer a mis compañeros de trabajo para que no utilicen conjuntos de datos para el desarrollo empresarial (.NET 2.0+) .