2008-08-25 14 views
117

Como alguien que no ha usado ninguna tecnología en proyectos del mundo real, me pregunto si alguien sabe cómo estos dos se complementan entre sí y cuánto se superponen sus funcionalidades.NHibernate vs LINQ to SQL

Respuesta

112

LINQ to SQL obliga a utilizar 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 usar un patrón domain driven design (que es lo que NHibernate facilita).

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, digamos que usted tiene una tabla de clientes con las siguientes columnas para mantener información de la dirección principal de un cliente:

  • StreetAddress
  • Ciudad
  • Estado
  • postal

Ahora, vamos a supongamos que también desea agregar columnas para la dirección postal del cliente para que agregue las siguientes columnas a la tabla Clientes:

  • MailingStreetAddress
  • MailingCity
  • MailingState
  • MailingZip

mediante LINQ to SQL, el objeto al cliente de su dominio ahora tendría las propiedades de 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.

Edit: @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 subóptimo.

+4

Puede codificar la implementación de su repositorio utilizando Linq To SQL, es muy útil. –

+1

Creo que no es ActiveRecord, incluso las clases mapeadas encapsulan parte de la lógica de la infraestructura. El patrón ActiveRecord sería si pudiera tener Customer.Save(). L2S implementa el patrón de unidad de trabajo con la clase DataContext, como Session en nHibernate, pero NH tiene un enfoque POCO real. –

+0

Maldita sea, L2S no está activo registrar de ninguna manera ... Registro activo significa que el objeto contiene toda la conectividad de la base de datos, con L2S no es un caso. –

5

¿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 la consulta como una construcción nativa. Puede consultar cualquier modelo de objeto que admita interfaces específicas (por ejemplo, IQueryable).

Muchas personas se refieren 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.

2

Por LINQ, asumo que quiere decir 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 la base 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.

0

O podría utilizar 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.

23

@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 un great series of posts on using Linq To SQL que le recomiendo encarecidamente que consulte.

No creo que se pueda decir que Linq y NHibernate se complementan entre sí, ya que eso implicaría que se podrían usar juntos, y mientras esto es posible, es mejor elegir uno y apegarse a él.

NHibernate le permite asignar sus tablas de base de datos a los objetos de su dominio de una manera altamente flexible. También le permite usar HBL para consultar la base de datos.

LINQ a SQL también permite asignar sus objetos de dominio a la base de datos sin embargo, utilizar la sintaxis de las consultas LINQ para consultar la base de datos

La diferencia principal aquí es que la sintaxis de las consultas LINQ es comprobar en tiempo de compilación el compilador 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 asignación. Necesitas hacer esto manualmente. Linq puede
hacer esto automáticamente para usted.

+15

¿Qué ocurre si está escribiendo código en una estructura de base de datos heredada que no puede cambiar porque es compatible con otras aplicaciones? ¿Desea que su modelo de dominio herede el diseño deficiente de la base de datos o desea crear un modelo de dominio enriquecido que pueda variar independientemente de la estructura de la base de datos? –

26

Dos puntos que se han pasado por alto hasta ahora:

  • LINQ a SQL no funciona con Oracle o cualquier base de datos, aparte de SqlServer. Sin embargo, terceros ofrecen mejor soporte para Oracle, p. devArt's dotConnect, DbLinq, Mindscape's LightSpeed y ALinq. (No tengo ninguna experiencia personal con éstos)

  • Linq to NHibernate permite que utilizó LINQ con un Nhiberate, por lo que puede eliminar una razón para no usar.

También el nuevo fluent interface to Nhibernate parece que sea menos doloroso para configurar la asignación de Nhibernate. (La eliminación de uno de los puntos de dolor de Nhibernate)


actualización

LINQ a Nhiberate es mejor en Nhiberate v3 que se encuentra ahora en alpha. Parece que Nhiberate v3 puede enviar hacia el final de este año.

El Entity Frame Work a partir de .net 4 también está empezando a parecer una opción real.

+2

Linq a NHibernate todavía está en una etapa muy temprana. No es una implementación completa, y podría decirse que no está lista para el uso de producción en absoluto. – liammclennan

+0

La nueva versión de LinqConnect 2.0 presenta algunas características adicionales para su comodidad, como el soporte de herencia Tabla por Tipo, compatibilidad con PLINQ y la funcionalidad de Actualizaciones por Lotes. ORM Designer (Desarrollador de Entidades Devart) ahora tiene compatibilidad con Model First y función de Sincronización de Mapeo. Más detalles: http://www.devart.com/news/2010/dotconnects600.html – Devart

7

Fluido NHibernate puede generar sus archivos de mapeo basados ​​en convenciones simples. Sin escritura XML y fuertemente tipado.

Recientemente he trabajado 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 utilizar 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 supongo que hay algunas herramientas para que NHibernate también lo haga ...

+2

Solo en caso de que otros lean su publicación y estén pensando en abandonar el barco también - '.ObjectTrackingEnabled = false' en su' DataContext' se habría resuelto su problema de seguimiento de cambios Siempre que acepte el patrón de unidad de trabajo y no desee realizar DDD, Linq-to-SQL realmente lo ofrece. – mattmc3

+0

"* necesitábamos cambiar de Linq a SQL a NHibernate por razones de rendimiento *" - Habiendo usado [Fluido, no menos] NHibernate durante algunos años, lo siento por usted. Creo que en su mayoría hicimos trampa y terminamos escribiendo SQL nativo para puntos de presión de rendimiento real. Sería interesante escuchar una actualización (seis años después ...) sobre cómo fue tu migración, y si valió la pena. – ruffin

0

Como escribiste "para una persona que no ha usado ninguno de ellos" LINQ to SQL es fácil de usar, así que cualquiera puede Úselo fácilmente También es compatible con los procedimientos, lo que ayuda la mayor parte del tiempo. Suponga que desea obtener datos de más de una tabla, luego escriba un procedimiento y arrástrelo al diseñador y creará todo para usted, Suponga que su nombre de procedimiento es "CUSTOMER_ORDER_LINEITEM" que obtiene 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>(); 

puede utilizar registros que se oponga por bucle foreach, así, que no es compatible con NHibernate

1

Primeros Vamos a separar dos cosas diferentes: modelado de bases está preocupado por los datos, mientras que el modelado de objetos es 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 se puedan usar 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. (Consulte 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 totalmente nuevos en los que las bases de datos tienen buenos nombres y poca complejidad, Linq-to-SQL puede ser una buena opción.

sin embargo se puede utilizar Fluido NHibernate con auto-asignaciones para este mismo propósito con el mapeo como convención. En este caso, no te preocupes por los correlacionadores de datos con XML o C# y deja que NHibernate genere el esquema de la base de datos a partir de tus entidades según una convención que puedes personalizar.

Por otro lado, la curva de aprendizaje de Linq-to-SQL es más pequeña que NHibernate.