Поддерживает ли NHibernate Criteria API проекции на свойства коллекции? - PullRequest
8 голосов
/ 13 мая 2009

Мне нужно повторить следующий рабочий HQL-запрос с использованием API критериев.

session.CreateQuery(
    "select c " +
    "from Parent p " +
    "inner join p.Children c " +
    "where p.Id = 9 " +
    "and c.Id = 33")
    .SetMaxResults(3)
    .List();

В запросе выбираются все дети, которые удовлетворяют определенным критериям и принадлежат родителям, которые удовлетворяют другим критериям. В моем примере оба критерия - это простые Id-равенства, но они могут быть чем угодно.

По какой-то причине запрос API эквивалентных критериев возвращает список с правильным количеством элементов, но все эти элементы равны нулю.

session.CreateCriteria(typeof (Parent))
    .Add(Restrictions.Eq("Id", 9))
    .CreateCriteria("Children")
    .Add(Restrictions.Eq("Id", 33))
    .SetProjection(Projections.Property("Children"))
    .SetMaxResults(3)
    .List();

Почему эти два запроса не возвращают одинаковые результаты?

Вот сгенерированный SQL из HQL-запроса:

SELECT   TOP 3 childid7_,
               name7_
FROM     (SELECT children1_.childid                 AS childid7_,
                 children1_.name                    AS name7_,
                 Row_number()
                   OVER(ORDER BY current_timestamp) AS __hibernate_sort_row
          FROM   dbo.parent parent0_
                 LEFT OUTER JOIN dbo.child children1_
                   ON parent0_.parentid = children1_.parentid
          WHERE  (parent0_.parentid = 9)
                 AND (children1_.childid = 33)) AS QUERY
WHERE    QUERY.__hibernate_sort_row > 0
ORDER BY QUERY.__hibernate_sort_row 

А вот SQL из запроса Criteria API:

SELECT   TOP 3 y0_
FROM     (SELECT this_.parentid                     AS y0_,
                 Row_number()
                   OVER(ORDER BY current_timestamp) AS __hibernate_sort_row
          FROM   dbo.parent this_
                 INNER JOIN dbo.child child1_
                   ON this_.parentid = child1_.parentid
          WHERE  this_.parentid = @p0
                 AND child1_.childid = @p1) AS QUERY
WHERE    QUERY.__hibernate_sort_row > 0
ORDER BY QUERY.__hibernate_sort_row 

Обратите внимание, что соединение между родителем и ребенком является однонаправленным. Дочерняя сущность не имеет ссылочного свойства, указывающего на ее родителя.

Кто-нибудь может предложить альтернативу, которая позволила бы мне обойти это ограничение?

Ответы [ 2 ]

1 голос
/ 26 августа 2009

Здесь вы найдете свойства 'только для запроса' http://ayende.com/Blog/archive/2009/06/10/nhibernate-ndash-query-only-properties.aspx

Это позволит вам сделать ссылку двунаправленной для ваших запросов.

1 голос
/ 24 августа 2009

Похоже, что вы хотите вернуть только детей, поэтому вам нужно изменить критерии, чтобы получить тип дочерних объектов, а затем использовать родительский идентификатор в качестве выбора.

session.CreateCriteria(typeof (Child))
.Add(Restrictions.Eq("Id", 33))
.CreateCriteria("Parent")
.Add(Restrictions.Eq("Id", 9))
.SetProjection(Projections.Property("Children"))
.SetMaxResults(3)
.List();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...