Список против Сета против Сумки в NHibernate
В чем разница между списком, набором и сумкой в файле сопоставления NHibernate? Как каждый относится к коллекциям.NET?
4 ответа
Семантика NHibernate:
Список: упорядоченный набор объектов, допускается дублирование. Используйте.NET
IList
в коде. Столбец индекса должен быть отображен в NHibernate.Set: неупорядоченный набор уникальных объектов, дубликаты не допускаются. использование
Iesi.Collection.ISet
в коде (NH до v4) илиSystem.Collections.Generic.ISet
(NH v4+). Важно переопределитьGetHashCode
а такжеEquals
указать бизнес-определение дубликата. Может быть отсортировано путем определения порядка или путем определения компаратора, что приводит кSortedSet
результат.Сумка: неупорядоченный список объектов, допускаются дубликаты. Используйте.NET
ICollection<T>
в коде. Столбец индекса в списке не отображается и не учитывается NHibernate.
Все эти объекты в NHibernate точно такие же, как и другие реализации этих абстрактных типов данных (ADT). Я был удивлен, насколько сложно найти наборы и сумки в Интернете из-за того, как часто встречаются названия для других вещей, поэтому я перечислил здесь некоторые ссылки и описания.
Для более подробной информации взгляните на следующее: Списки, Наборы и Сумки
Общие правила:
Списки по умолчанию упорядочены, используйте их, если вы хотите иметь возможность вытащить объект по его индексу или у вас странная любовь for
зацикливается foreach
петли. Вы не обязаны обращаться к ним в порядке, аналогичном тому, который вам необходим в связанном списке. Этот ADT позволяет дублировать.
Пожалуйста, обратите внимание! Хотя списки упорядочены так, как BryanD упомянул в своем ответе, абсолютно ничего не говорит о том, что они должны быть в том порядке, который вы ожидаете от базы данных при выполнении запроса HQL, если вы не укажете порядок по команде. Именно из-за этого некоторые люди предпочитают использовать комплект или сумки, чтобы не создавать иллюзию того, что их заказывают. Хотя я говорю это, в большинстве случаев они будут отображаться в видимом порядке, поскольку они добавляются в список в том порядке, в котором они находятся в запросе, который запускает NHibernate.
Наборы по умолчанию не упорядочены, вы не можете получить доступ к любой переменной напрямую через индекс. По умолчанию наборы являются единственными ADT из трех вышеупомянутых, которые поддерживают уникальность своих объектов. Это замечательно, если у вас есть коллекция, если вы не хотите содержать дубликаты.
Мешки (или мультисеты), как вы можете видеть из приведенных выше ссылок, являются типом Set, который позволяет объектам внутри него быть дубликатами других объектов. Обычно они не используются, так как упорядочение списков можно игнорировать и, следовательно, рассматривать как пакет.
Что касается того, как они используются в NHibernate, из базы данных ничего не извлекается по-разному, в зависимости от того, какой ADT вы здесь выбираете, именно то, для чего вы хотите его использовать, должно заставить вас выбрать другой ADT.
Лично я использую наборы для большинства вещей, поскольку я обычно требую, чтобы дочерние объекты были уникальными, и упорядочение не является проблемой. Хотя я буду использовать списки, где у меня есть группа объектов, которые я хочу упорядочить по чему-либо, например, по времени, чтобы достичь этого порядка, мне нужно вручную установить "порядок по" в HQL-запросе.
Ну, главное отличие состоит в том, что списки имеют неявный порядок элементов, проиндексированных по их положению в списке. Наборы и сумки также могут быть "заказаны", как правило, Компаратором или пунктом "заказ по", который применяется, когда эти предметы выходят из БД. Лично я никогда не использовал Bags ... если я знаю, что нужные мне данные упорядочены последовательно, я использую List, в противном случае я использую Set.
Набор не позволяет иметь повторяющиеся элементы в нем. Если вы попытаетесь добавить какой-либо новый элемент, он будет сравнивать (используется метод Equals) каждый элемент, который уже находится в коллекции, с тем, который вы добавляете, и, если один из них возвращает значение true, элемент не будет добавлен