Pregunta

¿Cómo puedo escribir el siguiente código SQL utilizando createCriteria:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
¿Fue útil?

Solución 3

He trabajado la manera de hacer esto utilizando la expresión isNotEmpty. Aquí está utilizando extensiones NHibernate Lambda:

Session.CreateCriteria<FooBar>()
    .Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
    .List<FooBar>();

Otros consejos

Aquí es cómo puede hacerlo:

var fooBars = Session.CreateCriteria<FooBar>()
        .Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();

... suponiendo que hay 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>();

Tras haber resuelto un problema relacionado con el tiempo y llegado a una solución que pensé en compartir la respuesta aquí:

Suponiendo que 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, digamos FooBarRef [en clase Fluido mapa que utilizan los () Método de Referencias], debe crear 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 la consulta de los padres dentro de la sub-consulta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top