Поскольку HQL и ICriteria являются инструментами доменных запросов, мне сложно ожидать такой функциональности.
AFAIK единственная близкая вещь - это использование Expression.Sql () из ICriteria, где вы запрашиваете суперкласс, но вводите специфичные для подкласса фрагменты с помощью чистого SQL.Там выражение будет выглядеть как
crit.Add(
Expression.Sql(@"(({alias}.DiscrimCol = :subClassADiscrimVal AND {alias}.Col2 = :barVal)
OR ({alias}.DiscrimCol = :subClassBDiscrimVal AND {alias}.Col3 = :barVal))",
new object[] { "subA", "subB", "bar" },
new IType[] { NHibernateUtil.String,NHibernateUtil.String,NHibernateUtil.String } )
);
не очень хорошо, но оно работает
Другим способом будет использование ISQLQuery
, который, по крайней мере, позволяет части SELECT быть зависящей от домена (ииспользуя .AddEntity()
), поэтому вы все еще можете выбрать управляемый суперкласс, а часть WHERE содержит отдельные фрагменты подкласса
========= ОБНОВЛЕНИЕ ==========
Во-вторых, есть способ реализовать это через HQL или ICriteria, но это скорее обходной путь и менее производительный, поскольку он включает подзапросы.пример в ICriteria:
nhSes.CreateCriteria(typeof(Super))
.Add(
Restrictions.Disjunction()
.Add(Subqueries.PropertyIn("Id", DetachedCriteria.For(typeof(ChildA))
.SetProjection(Projections.Id())
.Add(Restrictions.Eq("ChildAProp", barVal))))
.Add(Subqueries.PropertyIn("Id", DetachedCriteria.For(typeof(ChildB))
.SetProjection(Projections.Id())
.Add(Restrictions.Eq("ChildBProp", barVal))))
)
Я запрашиваю каждого дочернего элемента, проецирую его идентификатор, а затем выбираю суперкласс, ограничивая идентификаторы с IN из прогнозируемых дочерних идентификаторов.