2010-01-28 2 views
1

У меня есть тип сущности A. У кого много B. У объекта B есть много C.NHibernate: Count детей детей

Мне нужно подсчитать, сколько C имеет объект A. Как это можно сделать, используя API-интерфейс NHibernate?


Использование LINQ для NHibernate я не смог получить результаты, так как он вызывает исключение (см this question)

ответ

2

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

Способ, которым я бы это сделал, - найти все Cs, у которых есть B, который имеет данный A, а затем подсчитать найденные Cs.

Чтобы добавить ограничение на B из C, вы можете добавить псевдоним, а затем добавить ограничения на этот псевдоним. Чтобы выполнить запрос count, а не возвращать найденные Cs, вы можете использовать метод SetProjection и указать проекцию Count. Поскольку проекция count возвращает одно целочисленное значение, используйте UniqueResult для получения счета.

using (ISession session = SessionFactorySingleton.OpenSession()) 
{ 
    int numberOfCsForA1 = session.CreateCriteria<C>() 
     .SetProjection(Projections.Count("Id")) 
     .CreateAlias("B", "b") 
     .Add(Restrictions.Eq("b.A.Id", a1.Id)) 
     .UniqueResult<int>(); 

    // ... 
} 

SQL, порождена этого запроса выглядит следующим образом:

SELECT count(this_.Id) as y0_ 
    FROM [C] this_ 
    inner join [B] b1_ 
    on this_.IdB=b1_.Id 
    WHERE b1_.IdA = @p0;@p0 = 12 

Как вы можете видеть, это двухстороннее соединение, так как NHibernate достаточно умен, чтобы понять, что это не нужно присоединитесь к таблице A, чтобы получить идентификатор Bs A. Вместо этого он просто смотрит на значение IdA B.

+1

+1. Примечание для себя: это всегда CreateAlias ​​... –