Ответ 1
С момента, когда я разместил этот вопрос, мне удалось найти обходное решение/решение, которое другие могут найти полезным.
В принципе, в этом случае вы должны сначала создать другой запрос, который четко выбирает первичные ключи основного запроса вместе с разбиением на страницы. Поскольку DISTINCT (ID) вернет только те результаты, которые вы хотите, вы можете использовать разбиение на страницы SQL без каких-либо проблем. Затем вы повторно запускаете основной запрос без разбивки на страницы, но используете условие, в котором идентификатор находится в одном из возвращаемых списков. Я создал общий метод, который принимает критерии, просматривает возвращаемые идентификаторы и добавляет их как условие к основным критериям. Код ниже:
public static void LimitCriteriaByPrimaryKeys(this NHibernate.ICriteria criteria, string primaryKeyName, int pageNum, int pageSize)
{
var session = NHManager.Instance.GetCurrentSessionFromContext();
if (pageSize <= 0) pageSize = Int32.MaxValue - 1;
var nhSession = NHManager.Instance.GetCurrentSessionFromContext();
var pagingCriteria = (ICriteria)criteria.Clone();
IList ids = null;
var pKeyIDName = Projections.Property(primaryKeyName);
var pKeyProjection = Projections.Distinct(pKeyIDName);
{
{
//paging
pagingCriteria.SetProjection(pKeyProjection); //sets the primary key distinct projection
if (pageSize > 0)
{
if (pageNum < 1)
pageNum = 1;
int skipAmt = (pageNum - 1) * pageSize;
pagingCriteria.SetFirstResult(skipAmt);
pagingCriteria.SetMaxResults(pageSize);
ids = pagingCriteria.List(); //this returns the distinct list of IDs which should be returned for the given page & size
}
}
}
{
if (ids != null && ids.Count > 0)
{
criteria.Add(Expression.In(pKeyIDName, ids)); //adds the primary key restriction
var crit = criteria;
crit.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer());
}
else
{
criteria.Add(Expression.Eq(pKeyIDName, 0)); //this is added specifically so that the main criteria returns NO results
criteria.Add(Expression.Eq(pKeyIDName, 1));
}
}
}
Методы NHManager.Instance.GetCurrentSessionFromContext();
могут быть заменены вашим собственным методом для извлечения текущего сеанса из сеанса factory.
Надеюсь, что это поможет!