Этот запрос становится проще, если вы используете 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. Примечание для себя: это всегда CreateAlias ... –