NHibernate vs LINQ a SQL
linq-to-sql orm (9)
Como alguien que no ha usado ninguna tecnología en proyectos del mundo real, me pregunto si alguien sabe cómo se complementan estos dos y cuánto se superponen sus funcionalidades.
¿Puedes aclarar a qué te refieres con "LINQ"?
LINQ no es una tecnología de acceso a datos, es solo una característica de idioma que admite consultas como constructo nativo. Puede consultar cualquier modelo de objeto que admita interfaces específicas (por ejemplo, IQueryable).
Mucha gente se refiere a LINQ To SQL como LINQ, pero eso no es del todo correcto. Microsoft acaba de lanzar LINQ To Entities con .NET 3.5 SP1. Además, NHibernate tiene una interfaz LINQ, por lo que podría usar LINQ y NHibernate para obtener sus datos.
@ Kevin: Creo que el problema con el ejemplo que presenta es que está utilizando un diseño de base de datos deficiente. Pensé que crearías una tabla de clientes y una tabla de direcciones y normalizarías las tablas. Si lo hace, definitivamente puede usar Linq To SQL para el escenario que está sugiriendo. Scott Guthrie tiene una gran serie de publicaciones sobre el uso de Linq To SQL, que le sugiero que revise.
No creo que se pueda decir que Linq y NHibernate se complementan entre sí, ya que eso implicaría que podrían usarse juntos, y aunque esto es posible, es mucho mejor elegir uno y seguirlo.
NHibernate le permite mapear sus tablas de base de datos a sus objetos de dominio de una manera altamente flexible. También le permite usar HBL para consultar la base de datos.
Linq to SQL también le permite mapear sus objetos de dominio a la base de datos, sin embargo, utiliza la sintaxis de consulta de Linq para consultar la base de datos
La principal diferencia aquí es que el compilador comprueba la sintaxis de la consulta de Linq en tiempo de compilación para garantizar que sus consultas sean válidas.
Algunas cosas que debe tener en cuenta con linq es que solo está disponible en .net 3.x y solo es compatible con VS2008. NHibernate está disponible en 2.0 y 3.x, así como en VS2005.
Algunas cosas que debe tener en cuenta con NHibernate es que no genera sus objetos de dominio, ni genera los archivos de mapeo. Necesitas hacer esto manualmente. Linq puede
haz esto automáticamente por ti.
Como ha escrito "para una persona que no ha usado ninguno de ellos", LINQ to SQL es fácil de usar para que cualquiera pueda usarlo fácilmente. También admite procedimientos, lo que ayuda la mayor parte del tiempo. Supongamos que quiere obtener datos de más de una tabla, luego escribe un procedimiento y arrastra ese procedimiento al diseñador y creará todo para ti, supongamos que tu nombre de procedimiento es "CUSTOMER_ORDER_LINEITEM" que busca el registro de todas estas tres tablas y luego solo escribe
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
también puede usar el objeto de registros en el bucle foreach, que no es compatible con NHibernate
Dos puntos que se han perdido hasta ahora:
LINQ to SQL no funciona con Oracle o cualquier base de datos aparte de SqlServer. Sin embargo, terceros ofrecen mejor soporte para Oracle, por ejemplo, dotConnect de devArt , DbLinq , LightSpeed y ALinq . (No tengo ninguna experiencia personal con estos)
Linq a NHibernate le permite utilizar Linq con un Nhiberate, por lo que puede eliminar una razón para no usar.
Además, la nueva interfaz fluida para Nhibernate parece hacer menos doloroso configurar el mapeo de Nhibernate. (Eliminando uno de los puntos de dolor de Nhibernate)
Actualizar
Linq a Nhiberate es mejor en Nhiberate v3 que ahora está en alpha . Parece que Nhiberate v3 puede enviar hacia el final de este año.
El trabajo de marco de entidad a partir de .net 4 también comienza a parecer una opción real.
Fluidez NHibernate puede generar sus archivos de mapeo basados en convenciones simples. Sin escritura XML y fuertemente tipado.
Recientemente trabajé en un proyecto, donde tuvimos que cambiar de Linq a SQL a NHibernate por motivos de rendimiento. Especialmente la forma en que L2S materializa los objetos parece más lenta que lo que NHibernate dice y la administración del cambio también es bastante lenta. Y puede ser difícil desactivar la gestión de cambios para escenarios específicos donde no es necesaria.
Si va a usar sus entidades desconectadas del DataContext, en escenarios de WCF, por ejemplo, puede que tenga muchos problemas para volver a conectarlas al DataContext para actualizar los cambios. No he tenido problemas con NHibernate.
Lo que extrañaré de L2S es principalmente la generación de código que mantiene las relaciones actualizadas en ambos extremos de las entidades. Pero creo que hay algunas herramientas para que NHibernate también lo haga ...
LINQ to SQL te obliga a usar el patrón de tabla por clase. Los beneficios de utilizar este patrón son que es rápido y fácil de implementar y requiere muy poco esfuerzo para que su dominio se ejecute en base a una estructura de base de datos existente. Para aplicaciones simples, esto es perfectamente aceptable (y muchas veces incluso preferible), pero para aplicaciones más complejas, los desarrolladores a menudo sugieren utilizar un patrón de diseño impulsado por el dominio (que es lo que facilita NHibernate).
El problema con el patrón de tabla por clase es que la estructura de su base de datos tiene una influencia directa sobre el diseño de su dominio. Por ejemplo, supongamos que tiene una tabla Clientes con las siguientes columnas para contener la información de la dirección principal de un cliente:
- Dirección
- Ciudad
- Estado
- Cremallera
Ahora, supongamos que también desea agregar columnas para la dirección postal del cliente, de modo que agregue las siguientes columnas a la tabla Clientes:
- MailingStreetAddress
- MailingCity
- MailingState
- MailingZip
Con LINQ to SQL, el objeto Customer en su dominio ahora tendrá propiedades para cada una de estas ocho columnas. Pero si estuviera siguiendo un patrón de diseño impulsado por dominio, probablemente habría creado una clase de Dirección e hizo que su clase Cliente tuviera dos propiedades de Dirección, una para la dirección postal y otra para su dirección actual.
Es un ejemplo simple, pero demuestra cómo el patrón de tabla por clase puede conducir a un dominio algo apestoso. Al final, depende de ti. De nuevo, para aplicaciones simples que solo necesitan la funcionalidad básica CRUD (crear, leer, actualizar, eliminar), LINQ to SQL es ideal por su simplicidad. Pero personalmente me gusta usar NHibernate porque facilita un dominio más limpio.
Editar: @lomaxx - Sí, el ejemplo que utilicé fue simplista y podría haber sido optimizado para funcionar bien con LINQ to SQL. Quería mantenerlo lo más básico posible para llegar a casa. Sin embargo, sigue siendo cierto que hay varios escenarios en los que tener la estructura de su base de datos determinar la estructura de su dominio sería una mala idea, o al menos conducir a un diseño OO por debajo del óptimo.
O podría usar el proyecto Castle ActiveRecords. He estado usando eso por un tiempo breve para aumentar un código nuevo para un proyecto heredado. Utiliza NHibernate y funciona en el patrón de registro activo (sorprendente dado su nombre que conozco). No lo he intentado, pero supongo que una vez que lo haya utilizado, si siente la necesidad de recurrir directamente a la asistencia de NHibernate, no sería demasiado para hacerlo en parte o en todo su proyecto.
Por LINQ, supongo que te refieres a LINQ to SQL porque LINQ, por sí mismo, no tiene ninguna base de datos "activada" asociada. Es solo un lenguaje de consulta que tiene una carga de azúcar de sintaxis para que parezca SQL-ish.
En lo básico de ejemplos básicos, NHibernate y LINQ to SQL parecen resolver el mismo problema. Una vez que obtiene el pase, pronto se da cuenta de que NHibernate tiene soporte para muchas funciones que le permiten crear modelos de dominio verdaderamente completos. También hay un proyecto de LINQ to NHibernate que le permite usar LINQ para consultar NHibernate de la misma manera en que usaría LINQ to SQL.
Primero, separemos dos cosas diferentes: El modelado de bases de datos está preocupado por los datos, mientras que el modelado de objetos está preocupado por las entidades y las relaciones.
La ventaja de Linq a SQL es generar rápidamente clases fuera del esquema de la base de datos para que puedan usarse como objetos de registro activos (ver definición de patrón de diseño de registro activo).
La ventaja de NHibernate es permitir flexibilidad entre su modelado de objetos y modelado de bases de datos. La base de datos se puede modelar para reflejar mejor sus datos teniendo en cuenta el rendimiento, por ejemplo. Mientras que su modelado de objetos reflejará mejor los elementos de la regla de negocio usando un enfoque como el Diseño Dirigido por Dominio. (ver el comentario de Kevin Pang)
Con bases de datos heredadas con convenciones de modelado y / o nomenclatura deficientes, Linq-to-SQL reflejará estas estructuras y nombres no deseados en sus clases. Sin embargo, NHibernate puede ocultar este desorden con los mapeadores de datos.
En proyectos greenfield donde las bases de datos tienen un buen nombre y una baja complejidad, Linq-to-SQL puede ser una buena opción.
Sin embargo, puede usar Fluither NHibernate con asignaciones automáticas para este mismo fin con el mapeo como convención. En este caso, no se preocupe por los correlacionadores de datos con XML o C # y deje que NHibernate genere el esquema de la base de datos a partir de sus entidades según una convención que pueda personalizar.
Por otro lado, la curva de aprendizaje de Linq-to-SQL es más pequeña que NHibernate.