Что-то не так с Nhibernate Query Over fetch? - PullRequest
3 голосов
/ 03 июня 2011

У меня есть это

   using (ITransaction transaction = session.BeginTransaction())
        {
            Task tAlias = null;
            CompletedTask cAlias = null;

            List<Task> tasks = session.QueryOver<Task>(() => tAlias)
                .Where(Restrictions.In(Projections.Property(() => tAlias.Course.Id), courseIds))
                .Fetch(pt => pt.PersonalTaskReminders).Eager
                .List<Task>().ToList().ConvertToLocalTime(student);


            transaction.Commit();

            return tasks;
        }

    PersonalTaskReminders == Collection

Так что у задачи может быть много личных напоминаний.Я нахожу, хотя, если я установил 2 personalTaskReminders (так что PersonalTaskReminders теперь будет иметь 2 строки в своей коллекции из БД)

, что он возвращает одну и ту же задачу дважды.

Так что, если у меня было 50 personaltaskRemindersдля этой задачи.Я бы получил 50 результатов одной и той же задачи.Я не понимаю, почему.

Если я уберу энергичную загрузку.Я получаю одно задание из базы данных, как и ожидалось.

Ответы [ 2 ]

17 голосов
/ 03 июня 2011

Это очевидно, потому что активная выборка вызывает объединение с 2 таблицами. Чтобы избавиться от дублированных результатов, вы должны использовать DistinctRootEntityTransformer.

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

    var tasks = Session.QueryOver<Task>()
            .WhereRestrictionOn(x => x.Id).IsIn(courseIds)
            .Fetch(pt => pt.PersonalTaskReminders).Eager
            .TransformUsing(Transformers.DistinctRootEntity)
            .List<Task>();
1 голос
/ 24 сентября 2013

Решение Xelibrion является правильным способом решения проблемы.

Чтобы понять, почему результаты дублируются при выполнении Fetch, вы можете сравнить сгенерированный SQL:

Без Fetchполя в SELECT - это просто ваши корневые сущности Task поля.

С Fetch поля PersonalReminder сущностей были добавлены к SELECT.Таким образом, если у вас есть два PersonalReminder регистра для одного и того же Task, вы получите два регистра в результатах, и предложение DISTINCT не удалит их (поскольку реальные возвращаемые регистры отличаются, поскольку они содержат поля PersonalReminder).

SQL, сгенерированный с TransformUsing и без него, точно такой же, но NH обрабатывает возвращенные регистры для удаления дубликатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...