Nhibernate: отличные результаты в коллекции второго уровня - PullRequest
3 голосов
/ 07 февраля 2010

У меня есть такая объектная модель:

   class EntityA
   {
        ...
        IList<EntityB> BList;
        ...
   }

   class EntityB
   {
       ...
       IList<EntityC> CList;
   }

Мне нужно получить все наборы (Blist в EntityA и CList в EntityB), потому что, если все они понадобятся для выполнения некоторых операций, если я не буду загружать их, у меня будет проблема выбора n + 1. Итак, запрос был такой:

  select a from EntityA a left join fetch a.BList b left join fetch b.CList c

Первая проблема, с которой я столкнулся в этом запросе, заключалась в возврате дубликатов из БД, у меня были дубликаты EntityA из-за выборки левого соединения с BList. Быстро прочитав документацию по hibernate, было найдено несколько решений, во-первых, я попробовал отдельное ключевое слово, которое предположительно не будет реплицировать ключевое слово SQL, за исключением некоторых случаев, возможно, это был один из тех случаев, потому что у меня была ошибка SQL, говорящая, что я невозможно выбрать текстовые столбцы округа (столбец [Наблюдения] в таблице EntityA). Поэтому я использовал одно из других решений:

  query.SetResultTransformer(new DistinctRootEntityResultTransformer());

Это сработало нормально. Но результат операций все еще не прошел испытания. Я проверил дальше и обнаружил, что теперь есть дубликаты EntityB из-за левого соединения с CList.

Вопрос в том, как я могу использовать отличное в коллекции второго уровня? Я искал и нашел только решения для прямой дочерней коллекции корневого объекта, но не для дочерних коллекций второго уровня ...

Спасибо за ваше время

Ответы [ 3 ]

0 голосов
/ 16 февраля 2011

Используйте ISet вместо IList (и сопоставьте его как набор, конечно, вместо сумки).

Набор не допускает дублирование сущностей.

0 голосов
/ 06 января 2014

Я столкнулся с той же проблемой и не смог решить проблему с дублированием через hql. Тем не менее, я создал IEqualityComparer для всех коллекций и сделал Disinct () для каждой коллекции, чтобы исключить дублирование поверх результата hql.

0 голосов
/ 16 февраля 2011

Вы не можете выполнить то, что вы хотите, простым способом. Я считаю, что это выборка левого соединения C, которая вызывает дубликаты. Сгенерированный запрос выглядит примерно так:

select a 
left join a.b b
left join b.c c

и строки, возвращаемые БД, будут выглядеть так:

1: a1 | b1 | c1
2: a1 | b1 | c2
3: a1 | b2 | c3
4: a1 | b2 | c4
...

Несмотря на то, что вы уже отфильтровали дубликаты корневых объектов ( A ), из-за внешнего соединения на C БД должна возвращать повторяющиеся записи для таблицы B для каждой записи C . Простой способ решить эту проблему - отфильтровать элементы по коллекции утилит. В зависимости от требований вашей организации вы также можете использовать HashSet, чтобы он автоматически отфильтровывал их.

...