nHibernate QueryOver выполняет SubSelect для загрузки коллекции вместо соединения - PullRequest
0 голосов
/ 12 июля 2011

Хорошо, я пытаюсь загрузить много-много коллекций в мой объект User (Followers, Follow, PostLikes, CommentLikes).Однако, когда я выполняю левое соединение для этих коллекций, используя QueryOver, он возвращает больше записей, чем должно быть возвращено.

Я посмотрел на SQL с помощью SQL Profiler и, похоже, вместо того, чтобы просто производить 4 объединения, он создает 8 созданиянесколько зацикленный запрос.Это мой текущий запрос.

User userAlias = null;
        User followingAlias = null;
        User followersAlias = null;
        Post postLikesAlias = null;
        Comment commentLikesAlias = null;

        var entity = Session.QueryOver(() => userAlias)
            .Where(x => x.Id == id)
            .Left.JoinAlias(() => userAlias.Followers, () => followersAlias)
            .Left.JoinAlias(() => userAlias.Following, () => followingAlias)
            .Left.JoinAlias(() => userAlias.PostLikes, () => postLikesAlias)
            .Left.JoinAlias(() => userAlias.CommentLikes, () => commentLikesAlias)
            .SingleOrDefault();

        ReleaseCurrentSession();

        return entity;

Во всяком случае, когда я не загружаю вещи выборочно и использую энергичную загрузку через текущие отображения.Коллекции загружаются отлично.Я снова посмотрел на Sql Profiler, и кажется, что он выполняет отдельный запрос на выборку для каждой коллекции.Есть ли способ, которым я могу сделать это, используя QueryOver вместо использования объединений?Я знаю, что в ваших сопоставлениях вы можете указать FetchTypes, но когда я делаю это и просто использую .Fetch (x => x.Followers) и т. Д., Он все равно создает соединение!

Спасибо заранее,

Jon

Ответы [ 2 ]

0 голосов
/ 13 июля 2011

Вы не можете сделать это таким образом.NHibernate не выдает отдельные запросы для коллекций.Поэтому запрашивать коллекцию легко, когда вы имеете дело только с одной коллекцией вне корня.

Вы можете использовать CreateMultiCriteria (), чтобы создавать отдельные запросы, объединенные вместе, и преобразовывать их в один результат.1004 * В качестве альтернативы, я полагаю, что вы также можете использовать .Future () для каждого запроса, чтобы они были объединены вместе, NH будет использовать кэш первого уровня для сбора коллекций.

0 голосов
/ 13 июля 2011

Попробуйте использовать это как конец вашего запроса.

 .TransformUsing(new DistinctRootEntityResultTransformer())
 .SingleOrDefault();

или

 .TransformUsing(new DistinctRootEntityResultTransformer())
 .List();

и доступ к первому элементу.

...