Подтвердить что ты не робот

Предложение NHibernate: CreateCriteria и Exists

Как написать следующий SQL с помощью CreateCriteria:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
4b9b3361

Ответ 1

Я разработал, как это сделать, используя выражение IsNotEmpty. Здесь он использует расширения NHibernate Lambda:

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

Ответ 2

Вот как вы можете это сделать:

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

... если в объекте FooBar есть свойство коллекции (один ко многим) "Bazs".

В качестве альтернативы вы можете использовать отдельные критерии:

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>();

Ответ 3

Только что разрешив связанную проблему и, в конце концов, пришел к решению, я подумал, что отвечу здесь:

Предполагая, что вы хотите получить исходный запрос, с дополнительным условием в подзапросе:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
              AND Quantity = 5)

Предполагая, что у вас есть ссылка на класс Baz для родителя, вызванного, скажем, FooBarRef [в классе Fluent Map вы должны использовать метод References()], вы должны создать запрос следующим образом:

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>();

Я не на 100% убежден в жестком кодировании псевдонима "this", который является псевдонимом NHibernate, который автоматически присваивает корневой объект (таблицу) в запросе, но это единственный способ, которым я нашел ссылку на ключ таблицы родительских запросов из подзапроса.