Постраничные результаты NHibernate и неверное количество строк - PullRequest
1 голос
/ 10 марта 2011

У меня есть модель под названием «BusinessPage», которая может быть связана с 1 или более «BusinessPageCategories». Итак, у меня есть третья таблица с именем «BusinessPagesInCategories», которая связывает эти две.

Я пытаюсь получить постраничный набор записей BusinessPages вместе с общим количеством записей (у меня может быть всего 100 строк, но я возвращаю только 20 одновременно, но я возвращаю int, содержащий это общее число в дополнение к 20 рядов).

Проблема, с которой я столкнулся, заключается в том, что, поскольку я реализовал отношение «многие ко многим», оно возвращало одну и ту же строку BusinessPage x раз (где x - это число категорий, с которыми связана BusinessPage). Я хочу, чтобы возвращался только один экземпляр каждой бизнес-страницы. Поэтому я добавил следующее в свои критерии NHibernate, чтобы получить результаты Distinct BusinessPage.

.SetResultTransformer(CriteriaSpecification.DistinctRootEntity);

Хотя это работает для меня, поскольку теперь я правильно получаю по одной строке для каждой BusinessPage (а мое свойство Categories в каждой BusinessPage содержит правильные x категорий, которым оно назначено), мое количество строк равно not отражает этот «отдельный» счет - вместо этого, если у меня есть только 1 запись BusinessPage, которая связана с 3 категориями, количество строк равно 3!?!

BusinessPage (модель)

public virtual int BusinessPageId { get; private set; }
public virtual IList<BusinessPageCategory> Categories { get; set; }
public virtual string BusinessName { get; set; }

BusinessPageCategory (модель)

public virtual int CategoryId { get; private set; }
public virtual string CategoryName { get; set; }

BusinessPagesInCategories (таблица SQL, используемая для связи двух моделей)

BusinessPageId
CategoryId

Вот код, который я использую для получения своих «постраничных бизнес-страниц»:

public virtual IList<BusinessPage> GetPagedBusinessPages(int pageNumber, int pageSize, out int totalRecordCount)
{
    ICriteria c = CreateCriteria_BusinessPage()

        // we only want distinct business pages returned
        .SetResultTransformer(CriteriaSpecification.DistinctRootEntity);

    return c.PagedResults<BusinessPage>(pageNumber, pageSize, out totalRecordCount);
}

protected virtual ICriteria CreateCriteria_BusinessPage()
{
    return Session
        .CreateCriteria<BusinessPage>()
        .AddOrder(Order.Asc("BusinessName"));
}

А вот мои методы расширения для получения как постраничных результатов, так и количества всех важных строк.

public static IList<T> PagedResults<T>(this ICriteria criteria, int pageNumber, int pageSize, out int totalRecordCount)
{
    var results = criteria
        .CloneNewCriteria()
        .SetPaging(pageNumber, pageSize)
        .Future<T>();

        totalRecordCount = criteria.GetTotalCount().Value;

        return results.ToList<T>();
}

public static ICriteria CloneNewCriteria(this ICriteria criteria)
{
    return CriteriaTransformer.Clone(criteria);
}

public static ICriteria SetPaging(this ICriteria criteria, int pageNumber, int pageSize)
{
    return criteria
        .SetMaxResults(pageSize)
        .SetFirstResult((pageNumber - 1) * pageSize);
}

public static IFutureValue<int> GetTotalCount(this ICriteria criteria)
{
    criteria.ClearOrders();

    return criteria
        .SetProjection(Projections.RowCount())
        .FutureValue<int>();
}

Я все еще очень плохо знаком с NHibernate, так что может быть простое решение для этого?

1 Ответ

0 голосов
/ 11 марта 2011

Проблема решена. Оказывается, я настраивал псевдоним для категорий независимо от того, нужно ли мне фильтровать по категориям или нет, поэтому объединение было установлено в сценарии, который мне не нужен, и в результате возвращал повторяющиеся строки (по одному на каждое объединение по категориям)!

В сценарии, в котором мне нужно передать идентификатор категории и отфильтровать результаты по этой категории, в объединениях нет повторяющихся строк, поскольку каждой бизнес-странице может быть назначена любая 1 категория только один раз.

Мне показалось странным, что он делал это объединение с категориями, хотя я и не хотел ссылаться на объект категорий, пока не вернулись исходные записи, но похоже, что создается этот псевдоним вне требуемой области, принудительное объединение и загрузка этих категорий без необходимости.

...