Список против Set против Bag в NHibernate - PullRequest
101 голосов
/ 16 декабря 2009

В чем разница между списком, набором и сумкой в ​​файле сопоставления NHibernate? Как каждый относится к коллекциям .NET?

Ответы [ 4 ]

220 голосов
/ 17 декабря 2009

Семантика NHibernate:

  1. Список: упорядоченный набор объектов, допускается дублирование. Используйте .NET IList в коде. Столбец индекса необходимо сопоставить в NHibernate.

  2. Set: Неупорядоченный набор уникальных объектов, дубликаты не допускаются. Используйте Iesi.Collection.ISet в коде (NH до v4) или System.Collections.Generic.ISet (NH v4 +). Важно переопределить GetHashCode и Equals, чтобы указать бизнес-определение дубликата. Может быть отсортировано путем определения порядка или путем определения компаратора, результатом которого будет SortedSet результат.

  3. Сумка: неупорядоченный список объектов, допускаются дубликаты. Используйте .NET ICollection<T> в коде. Столбец индекса в списке не отображается и не учитывается NHibernate.

21 голосов
/ 17 декабря 2009

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

Для получения более подробной информации смотрите следующее: Списки , Наборы и Сумка

Общие правила:

Списки по умолчанию упорядочены, используйте их, если вы хотите иметь возможность извлекать объект по его индексу или у вас есть странная любовь for петель над foreach петлями. Вы не обязаны получать к ним доступ в порядке, необходимом для Связанного списка . Этот ADT позволяет дублировать.

Обратите внимание! Хотя списки упорядочены так, как BryanD упомянул в своем ответе, абсолютно ничего не говорит о том, что это должно быть в порядке, который вы ожидаете от базы данных, когда вы выполняете HQL-запрос, если вы не укажете порядок по команде. Из-за этого некоторые люди предпочитают вместо этого использовать Set или Bags, чтобы он не создавал иллюзию того, что заказан. Хотя я говорю это, в большинстве случаев они будут отображаться в видимом порядке, поскольку они добавляются в список в том порядке, в котором они найдены в запросе, который запускает NHibernate.

Наборы являются не по умолчанию, вы не можете получить доступ к любой переменной напрямую через индекс. По умолчанию наборы являются только ADT из трех вышеупомянутых, которые поддерживают уникальность своих объектов . Это замечательно, если у вас есть коллекция, если вы не хотите содержать дубликаты.

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

Что касается того, как они используются в NHibernate, из базы данных ничего не извлекается по-разному, в зависимости от того, какой ADT вы здесь выбираете, именно то, для чего вы хотите его использовать, должно заставить вас выбрать другой ADT.

Лично я использую наборы для большинства вещей, так как я обычно требую, чтобы дочерние объекты были уникальными, и упорядочение не является проблемой. Хотя я буду использовать списки, в которых у меня есть группа объектов, которые я хочу упорядочить по чему-либо, например, по времени, чтобы достичь этого порядка, мне нужно вручную установить «порядок по» в HQL-запросе.

1 голос
/ 16 декабря 2009

Ну, главное отличие состоит в том, что списки имеют неявный порядок элементов, проиндексированных по их позиции в списке. Наборы и сумки также могут быть «заказаны», как правило, Компаратором или пунктом «заказ по», который применяется, когда эти предметы выходят из БД. Лично я никогда не использовал Bags ... если я знаю, что нужные данные упорядочены последовательно, я использую List, в противном случае я использую Set.

0 голосов
/ 17 декабря 2009

Набор не позволяет иметь повторяющиеся элементы в нем. Если вы попытаетесь добавить какой-то новый элемент, он будет сравнивать (используется метод Equals) каждый элемент, который уже находится в коллекции, с тем, который вы добавляете, и, если один из них возвращает значение true, элемент не будет добавлен

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