Список против набора против сумки в NHibernate

109

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

mrblah
источник

Ответы:

230

Семантика NHibernate:

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

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

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

Майкл Гаттузо
источник
Re: # 2, нельзя ли использовать ISetвместо обычного Iesi?
Сергей Таченов
@SergeyTachenov: см stackoverflow.com/questions/9222058/... для возможного ответа. Когда был написан этот ответ, ISet не был частью .net
Майкл Гаттузо
Наименее популярный ответ на этот вопрос - да, начиная с NHibernate 4. Так что, возможно, этот вопрос тоже нужно отредактировать.
Сергей Таченов
21

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

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

Общие правила таковы:

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

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

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

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

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

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

Джей
источник
2
Исправление в списке - использование списка в файле сопоставления NHibernate БУДЕТ требует сопоставления столбца индекса. Таким образом, список будет вытянут в том же порядке, в котором он был помещен.
Майкл Гаттузо
@Michael Gattuso Хороший момент, я должен был упомянуть в ответе выше, что я говорил о запросах HQL (отсюда и комментарий «порядок по»), а не о фактической спецификации коллекции в вашем файле сопоставления.
Джей
Одним из преимуществ использования пакетов является то, что их не нужно загружать из базы данных, когда вы добавляете в нее новые элементы. Никаких дубликатов для проверки, никакого порядка для определения.
tvaananen 03
1

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

BryanD
источник
0

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

лукавый
источник