Этот запрос становится проще, если вы используете C в качестве начальной точки запроса, а не A. Это возможно, поскольку вы используете двунаправленные отображения в соответствии с отображением, которое вы показываете в своем другом вопросе.
Я бы сделал так, чтобы найти все C, у которых есть B, у которого есть данный A, и затем посчитать найденные C.
Чтобы добавить ограничение на B C, вы можете добавить псевдоним, а затем добавить ограничения к этому псевдониму. Чтобы выполнить запрос подсчета, а не возвращать найденные C, вы можете использовать метод SetProjection и указать проекцию 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.