¿Cómo se puede escribir el siguiente código SQL utilizando createCriteria:NHibernate: createCriteria y existe cláusula
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
¿Cómo se puede escribir el siguiente código SQL utilizando createCriteria:NHibernate: createCriteria y existe cláusula
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
me funcionó cómo hacer esto utilizando la expresión isNotEmpty. Aquí está utilizando NHibernate Extensiones Lambda:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();
Aquí es cómo puede hacerlo:
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
... suponiendo que no es una propiedad de colección (uno a muchos) "Bazs" en el objeto FooBar.
Como alternativa puede usar criterios unifamiliares así:
DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
.SetProjection(Projections.Property("baz.FooBarId"))
.Add(Restrictions.EqProperty("baz.FooBarId", "fooBar.Id"));
var fooBars = Session.CreateCriteria<FooBar>("fooBar")
.Add(Subqueries.Exists(dCriteria)).List<FooBar>();
Habiendo resuelto un problema relacionado y finalmente llegó a una solución que pensé en compartir la respuesta aquí:
Suponiendo desea que la consulta pregunta original, con una condición adicional en la sub-consulta:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
AND Quantity = 5)
Asumiendo que tiene una referencia a la clase Baz al padre, llamado, por ejemplo FooBarRef [en clase Fluido mapa que utilizan las Referencias() método], se crearía la consulta de la siguiente manera:
DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
.SetProjection(Projections.Property("baz.FooBarId"))
.Add(Expression.EqProperty("this.FooBarId", "FooBarRef.Id"))
.Add(Expression.Eq("baz.Quantity", 5));
var fooBars = Session.CreateCriteria<FooBar>("fooBar")
.Add(Subqueries.Exists(dCriteria)).List<FooBar>();
no estoy 100% convencido de codificación dura del alias "este", que es el alias NHibernate asigna automáticamente a la entidad raíz (tabla) en la consulta, pero es la única forma que he encontrado para hacer referencia a la clave de la tabla de consulta principal desde dentro de la subconsulta.
De hecho ... y me dio la idea de que se puede hacer de una manera más simple y sin las extensiones Nhibernate Lambda. He editado mi respuesta para incluir esa opción. – tolism7