NHibernate - как обеспечить уникальность?

Мой сценарий таков:

  • У меня есть объекты (сообщения), которые можно пометить
  • Итак, у меня есть объект Tag и отношение "многие ко многим"
  • Вышесказанное сделано и работает
  • Теперь при добавлении тегов я хотел бы сохранять новые теги только в том случае, если они не существуют (где наличие проверяется по заголовку тега)
  • если тег уже существует, я бы хотел, чтобы он был распознан и прикреплен к моему объекту вместо нового

Какой самый простой / самый чистый способ сделать это?

Кстати, по некоторым причинам я хотел бы использовать искусственный первичный ключ (числовой идентификатор) для моей сущности Tag.

Спасибо!


person Michał Chaniewski    schedule 19.06.2009    source источник


Ответы (2)


У вас есть отношение «многие ко многим», которое вы можете выразить в своих бизнес-классах и сопоставить с NHibernate. Структура связывающей таблицы, которая разрешает отношение «многие ко многим», не позволит объекту быть привязанным к одному и тому же тегу более одного раза.

Единственный способ обеспечить соблюдение правила в вашем вопросе - это код. Последовательность задач будет примерно такой:

  1. Разбить список тегов, введенный пользователем, на отдельные теги
  2. Прокручивать теги ...

    а. Если тег существует, добавьте его в коллекцию тегов объекта.

    б. В противном случае создайте новый тег и добавьте его в коллекцию тегов объекта.

  3. Сохранять объект

Вам нужно будет добавить логику для поиска существующих тегов с учетом орфографических ошибок, использования заглавных букв и альтернативного использования. Например, вы не хотите иметь теги, которые означают одно и то же, но не являются равными строками, например «ASPNET», «ASP.NET» или «asp.net». Качество вашего списка тегов будет зависеть от того, насколько надежен код, проверяющий существующие теги.

person Jamie Ide    schedule 19.06.2009

Чтобы уточнить - тег может быть закреплен на многих объектах, а объект может иметь много тегов. Вот что для меня значат отношения "многие ко многим". Вы это имеете в виду?

Когда вы делаете это в SQL, у вас есть таблицы с именами TAG и OBJECT и объединенная таблица с именем TAG_OBJECT, которая содержит два столбца, по одному для каждого первичного ключа в других таблицах. Первичный ключ в таблице соединения TAG_OBJECT - это пара (TAG_ID, OBJECT_ID). Это гарантирует уникальное сочетание для каждой строки.

Если вы используете Hibernate, вы просто добавляете список или коллекцию объектов в качестве частного члена данных в свой класс Tag, а список или коллекцию тегов в качестве частного члена данных в свой класс Object.

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

Вы также должны добавить уникальное ограничение к атрибуту заголовка тега. Вот пример, который вам не совсем подходит, потому что это Java и XML, но, возможно, этой подсказки будет достаточно, чтобы подсказать вам, где искать NHibernate:

<element column="serialNumber" type="long" not-null="true" unique="true"/>

В вашем случае столбец будет заголовком тега, тип - строкой, а остальные флаги останутся такими же, как в примере.

person duffymo    schedule 19.06.2009
comment
Да, вот что я имею в виду. Часть отношений сделана и работает, теперь я пытаюсь сделать теги уникальными. Для дальнейшего обсуждения предположим, что объекты, которые я помечаю, являются сообщениями - это всего лишь один тип сущности. - person Michał Chaniewski; 19.06.2009
comment
Я думаю, Hibernate справится с этим. Возможно, вам нужно добавить уникальное ограничение для атрибута title. - person duffymo; 19.06.2009
comment
Он работает таким образом, что вызывает исключение при нарушении уникальности. Я могу справиться с этим, но я ищу более чистый способ ... - person Michał Chaniewski; 19.06.2009
comment
Как будет выглядеть очиститель? Вот как это делает Hibernate. Если вы хотите, чтобы произошло что-то еще, вам придется найти другую технологию. - person duffymo; 20.06.2009