Этот запрос становится проще, если вы используете 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 таблицы. Б.
person
Erik Öjebo
schedule
28.01.2010