c# - icriterion - nhibernate sql query string
Reescribiendo la aplicaciĆ³n NHibernate en Linq a SQL (6)
Cuando estoy construyendo una aplicación, y tiene un dominio simple y un esquema básico, me encanta Linq2Sql. Linq es rápido para escribir, y puedo hacer las cosas rápidamente. Me doy cuenta de que hay un Linq2NHibernate por ahí, pero no estoy seguro de cuál es su madurez. Algunas desventajas, IMO a Linq2Sql, tienen que regenerar las clases y el DataContext cada vez que el esquema cambia, y tener que mapear desde clases generadas por Linq2Sql, en mis objetos de dominio. Para pequeños proyectos fáciles, realmente no me importa hacer esto. Aunque con FluentNHibernate y Linq2NHibernate, podría ser igual de eficiente con NHibernate que con Linq2Sql, pero no lo he intentado.
Estaba en un proyecto que estaba usando Linq2Sql en una base de datos demasiado normalizada con un dominio algo complejo, y era una pesadilla. Funcionó, y pudimos luchar con un buen rendimiento, pero la capacidad de mantenimiento casi no existía. Pero con el esquema como estaba, no estoy seguro de que NHibernate, o SQL directo, hubiera cambiado eso. Este es un caso en el que sin duda alguna, en mi mente, una base de datos de documentos habría sido el camino a seguir.
Si el proyecto ya estaba hecho con NHibernate, y tienes esa experiencia, me quedaré con eso. El hecho de que puedas mapear directamente a tus objetos de dominio es genial. La generación de código Linq2Sql puede ser un problema cuando el esquema está cambiando temprano en el desarrollo. Además de eso, Linq2Sql está efectivamente muerto. MS está poniendo todos sus huevos ORM en la cesta del Entity Framework.
Tengo una aplicación obsoleta vieja escrita usando NHibernate. Ahora me gustaría reescribirlo, incluida la nueva funcionalidad y los grandes cambios en el modelo.
¿Cuáles son las principales desventajas de utilizar Linq a SQL en lugar de NHibernate?
¿Cuáles son los posibles problemas del uso de LINQ to SQL? ¿Hacer que DataContext sea algo así como singleton puede dar un rendimiento deficiente?
En lugar de hacer un puerto completo, tal vez todo lo que necesita es LINQ-ify su capa de NHibernate ...
http://www.hookedonlinq.com/LINQToNHibernate.ashx
Un poco de material de lectura adicional:
http://www.caffeinatedcoder.com/linq-to-nhibernate/
Citar:
Gracias al nuevo proveedor NHibernate LINQ, ahora puedo trabajar en un modo que no solo es más seguro, sino que también es mucho más legible.
Mire estas preguntas antes y después y juzgue por usted mismo:
Antes (Criterion API)
1: public IList<Call> GetCallsByDate(DateTime beginDate, int interpreterId)
2: {
3: ICriteria criteria = Session.CreateCriteria(typeof(Call))
4: .CreateAlias("Customer", "Customer")
5: .Add(Restrictions.Gt("StartTime", beginDate))
6: .Add(
7: Restrictions.Or(
8: Restrictions.Lt("EndTime", DateTime.Now), Restrictions.IsNull("EndTime")
9: )
10: )
11: .Add(Restrictions.Eq("Interpreter.Id", interpreterId))
12: .AddOrder(Order.Desc("StartTime"))
13: .AddOrder(Order.Desc("Customer.Name"));
14:
15: return criteria.List<Call>() as List<Call>;
16: }
Después (LINQ to NHibernate)
1: public IList<Call> GetCallsByDateWithLinq(DateTime beginDate, int interpreterId)
2: {
3: var query = from call in Session.Linq<Call>()
4: where call.StartTime > beginDate
5: && (call.EndTime == null || call.EndTime < DateTime.Now )
6: && call.Interpreter.Id == interpreterId
7: orderby call.StartTime descending, call.Customer.Name
8: select call;
9:
10: return query.ToList();
11: }
Una gran pregunta, pero una cosa de la que me enteré durante un gran refactor de L2S a NHibernate 2.x es que NHibernate permite que una clase base se represente en una tabla física diferente a la derivada. Pero con L2S me vi obligado a usar 1 sola tabla para representar la base y cada clase que la extendería.
Esto me permitió crear tablas más pequeñas porque tenía una clase base heredada por aproximadamente 25 variaciones diferentes de clases secundarias. Si desea utilizar esta funcionalidad en el futuro, podría ayudar a simplificar su esquema.
¿Cuáles son las principales desventajas de utilizar Linq a SQL en lugar de NHibernate?
Ventajas de LINQ to SQL
- Sintaxis de consulta más avanzada y fácil de usar (en mi humilde opinión), específicamente usa LINQ para realizar consultas, lo que le da a usted fuertes consultas de tiempo de compilación / tipeado. NHibernate te da HQL, que aunque bastante poderoso, está basado en cadenas. NHibernate también tiene consultas de Criteria que se escribieron un poco más fuertemente (aún algunas cadenas), pero su sintaxis / API es bastante difícil de entender.
NHibernate v2 tiene un proveedor de LINQ que puede descargar, pero le falta un poco (de hecho, le falta), muchos casos de uso no son compatibles. NHibernate 3.0 viene con su propio proveedor de LINQ incorporado que es mucho más potente, casi a la par con LINQ 2 SQL o EF.
Desventajas con LINQ to SQL
¡Casi TODO lo demás! En serio, ¿dónde empiezo?
Tabla simple a mapeo de entidades, a diferencia de NHibernate, que tiene capacidades de mapeo más potentes, incluyendo: asociaciones unidireccionales, mapeo de componentes, puede mapear colecciones de tipos de valores como
public IList<string> Tags {get; set; }
public IList<string> Tags {get; set; }
public IList<string> Tags {get; set; }
, mapeo de herencia (muy poderoso), mapeo de Enum, y más ...Sus entidades se acoplan estrechamente a LINQ to SQL, lo que puede afectar las pruebas unitarias. NHibernate es compatible con el mapeo de POCO, importante para la implementación de una base de código comprobable unitariamente, mantenible y mantenible para la unidad.
Admite más bases de datos (SQL Server, MySql, PostgreSQL, Oracle, SQLite, y más). LINQ 2 SQL solo es compatible con MS SQL Server.
Posibilidad de implementar los principios de DDD (Diseño Dirigido por Dominio) en su aplicación con NHibernate. LINQ 2 SQL es más una vista centrada en la base de datos de su modelo de dominio, mientras que NHibernate adopta una visión más centrada en el negocio / comportamiento de su dominio.
En serio, tomar una aplicación NHibernate y ''degradarla'' a LINQ 2 SQL parece un paso atrás. Si desea usar algo más Microsofty, al menos considere usar Entity Framework 4.0. LINQ 2 SQL tiene su lugar con aplicaciones más simples con solo unas pocas tablas, pero cualquier cosa más complicada necesita un ORM más poderoso.
si mal no recuerdo, Linq2Sql no admite muy bien las relaciones entre muchas y muchas tablas
http://www.chrisbrandsma.com/2007/08/linq-to-sql-many-to-many-tables-and.html
De "El falso mito de encapsular el acceso a datos en el DAL" :
"Me gustaría diseñar un sistema / aplicación utilizando NHibernate. Pero también quiero ser tan flexible que, en el futuro, si desconecto el NHibernate y uso el marco de Entidad ADO.NET u otro marco, entonces mi aplicación no debería fallar".
En resumen, estoy completamente en contra de intentar hacer algo así.
Se basa en suposiciones erróneas
Gran parte del impulso detrás de esto se basa en la unidad histórica construida en el tiempo en que las capas de acceso a datos accedían directamente a una base de datos utilizando su propio dialecto, lo que resultaba en la necesidad de crear dicha encapsulación para admitir múltiples bases de datos.
El problema con este disco es que ya no es un factor, todos los OR / M modernos pueden manejar múltiples bases de datos de manera efectiva. Además, las OR / M modernas ya no son solo formas de ejecutar SQL y obtener un resultado, que es cómo se escribieron los DAL antiguos. Un OR / M asume muchas más responsabilidades, desde cosas como el seguimiento de cambios hasta la gestión de caché, desde garantizar la concurrencia optimista hasta la gestión de una comunicación óptima con la base de datos.
Y esas características importan mucho. No solo eso, sino que son diferentes entre cada OR / M.
No funciona, y lo sabrás demasiado tarde
El problema principal es que no importa cuánto lo intentes, habrá diferencias sutiles y no tan sutiles entre diferentes OR / M, esos cambios pueden afectar drásticamente la forma en que creas tu aplicación.
Entonces, ¿cómo te mueves entre OR / M?
Hay razones por las cuales algunas personas quieren pasar de una tecnología de acceso a datos a la otra. Estuve involucrado en varios de esos esfuerzos, y el enfoque que utilizamos en cada uno de esos casos fue portar , en lugar de intentar lanzar una nueva implementación de IDataAccess.