Левое объединение, выделение и разбиение на страницы с помощью QueryOver - PullRequest
2 голосов
/ 20 декабря 2011

У меня есть такая проблема, которая кажется распространенной, но на самом деле ни одно из решений от SO и Google не работает для меня.

Давайте рассмотрим такую ​​ситуацию (очень похоже на мою):

    public class User
    {
     public int Id;
     public string Name;
     //30 other fields;
     public IList<Role> Roles;
    }

    public class Role
    {
     public int RoleNumber;
     public int UserId;
    }

1 У пользователя может быть 0-много ролей.

Я хочу отобразить в списке пользователей в gridviewс его полями и дополнительным столбцом «Роли», в котором будут отображаться все его номера ролей (с использованием повторителя).Для этого мне нужно получить список пользователей с его ролями.

Можно ли создать такой запрос с помощью QueryOver?Все решения из Интернета говорят, что я должен создать подзапрос, который будет идентифицировать Ids, а затем второй запрос, который вернет Users, идентификатор которого находится в подзапросе.Он работает и возвращает мне различаемый список, но без ролей, поэтому NH генерирует дополнительный выбор для каждого пользователя, чтобы получить эту недостающую информацию.

Мой запрос:

Role roles = null;
User users = null;
IQueryOver<User,User> userQuery = ... 
IQueryOver<User,User> distQuery = ...
distQuery.JoinAlias(f=> f.Roles, () => Roles, JoinType.LeftOuterJoin)
         .Select(Projections.Distinct(Projections.Id()));

userQuery.WithSubquery.WhereProperty(g => g.Id).In<User>((QueryOver<User>)    distQuery) //and other joins, wheres etc.

возвращает различимый список без ролей

Если я добавлю второе присоединение к ролям, он вернет список с ролями и дубликатами

Если я добавлю второе присоединение к ролям и использую

TransformUsing(new DistinctRootEntityResultTransformer())

Он вернет выделенный список сПользователи и их роли, но подкачка страниц не будут работать, и RowCount () вернет неправильный номер.

Есть идеи, что я могу сделать?

1 Ответ

3 голосов
/ 20 декабря 2011

В основном то, что вы запрашиваете, в настоящее время не поддерживается с помощью NHibernate.Вы не можете загружать Users и Roles и следить за разбиением на страницы.

Сначала я получу постраничный список пользователей (например, 25), а затем отложенно загружаю роли по мере необходимости.

Session.QueryOver<User>().Skip(x).Take(25);

и измените свой файл сопоставления на: -

<bag class="Role" Name="Roles" batch-size='25' ...>
...
</bag>

При этом будет отправлен один запрос для получения списка разбитых на страницы Users, затем будет выполнен второй запрос, чтобы получить все роли для пользователей.,Это, безусловно, самый эффективный способ.

...