НГибернейт:Предложение CreateCriteria и Exists
-
20-09-2019 - |
Вопрос
Как я могу написать следующий SQL, используя CreateCriteria:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
Решение 3
Я придумал, как это сделать, используя выражение IsNotEmpty.Здесь используются расширения NHibernate Lambda:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();
Другие советы
Вот как вы можете это сделать:
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>();
Только что решив связанную проблему и в конечном итоге придя к решению, я решил поделиться ответом здесь:
Предположим, вам нужен исходный запрос вопросов с дополнительным условием в подзапросе:
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 автоматически присваивает корневому объекту (таблице) в запросе, но это единственный способ, который я нашел для ссылки на ключ таблицу родительского запроса из подзапроса.