NHibernate: Subqueries.Exists не работает - PullRequest
3 голосов
/ 05 марта 2010

Я пытаюсь получить sql, как показано ниже, используя критерии API NHibernate:

SELECT * FROM Foo
   WHERE EXISTS (SELECT 1 FROM Bar 
                 WHERE Bar.FooId = Foo.Id
                 AND EXISTS (SELECT 1 FROM Baz
                            WHERE Baz.BarId = Bar.Id)

Так что в основном у Фоо есть много баров, а у баров много баз. Я хочу получить все фу, у которых есть слитки с базой.

Для этого лучше всего подойдет отдельный критерий, например:

var subquery = DetachedCriteria.For<Bar>("bar")
    .SetProjection(Projections.Property("bar.Id"))
    .Add(Restrictions.Eq("bar.FooId","foo.Id")) // I have also tried replacing "bar.FooId" with "bar.Foo.Id"
    .Add(Restrictions.IsNotEmpty("bar.Bazes"));

return Session.CreateCriteria<Foo>("foo")
     .Add(Subqueries.Exists(subquery))
     .List<Foo>();

Однако это вызывает исключение: System.ArgumentException: Не удалось найти поставщика информации о критериях соответствия для: bar.FooId = foo.Id и bar.Bazes не пусто

Это ошибка с NHibernate? Есть ли лучший способ сделать это?

Ответы [ 2 ]

3 голосов
/ 05 марта 2010

Попробуйте создать критерии или псевдоним для пути Foo в классе Bar в вашем подзапросе, а затем примените ограничение eaual.

var subquery = DetachedCriteria.For<Bar>("bar")
    .SetProjection(Projections.Property("bar.Id"))
    .Add(Restrictions.IsNotEmpty("bar.Bazes"))
    .CreateCriteria("Foo")
         .Add(Restrictions.Eq("bar.FooId","Id"));

или CreateAlias ​​("Foo", "foo")

var subquery = DetachedCriteria.For<Bar>("bar")
    .SetProjection(Projections.Property("bar.Id"))
    .Add(Restrictions.IsNotEmpty("bar.Bazes"))
    .CreateAlias("Foo","foo")
    .Add(Restrictions.Eq("bar.FooId","foo.Id"));
2 голосов
/ 06 июня 2011

Я только что решил ту же проблему, с которой столкнулся.

Решение для меня заключалось в том, чтобы квалифицировать внешний ключ «дочерней» сущности (указывающий на родительскую сущность) с помощью «свойства сопоставленной ссылки» для этого родителя.

Кроме того, поскольку ваш 'childEntity.FK = parentEntity.Key "фактически приравнивает свойство к свойству, которое вы хотите использовать Expression.EqProperty (.., ..), а не Expression.Eq (.., ..)

Итак, я предлагаю изменить эту строку:

Add(Restrictions.Eq("bar.FooId","foo.Id")) 

К этому:

.Add(Restrictions.EqProperty("bar.Foo.Id","foo.Id")) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...