В nHibernate можно ли сопоставить абстрактный базовый класс с коллекцией? - PullRequest
1 голос
/ 17 ноября 2009

У меня есть базовый класс для элементов контента в CMS, которую я создаю. В настоящее время он помечен как абстрактный, потому что я хочу, чтобы производные классы создавались только. Производные классы, такие как BlogPost, Article, Photo и т. Д., Устанавливаются как присоединенный подкласс к моему классу ContentBase в nHibernate.

Я пытаюсь настроить отображение «многие ко многим» между этим классом и классом Tag. Я хочу иметь коллекцию тегов в классе ContentBase и коллекцию элементов ContentBase в классе тегов.

Позволит ли nHibernate отобразить абстрактный класс ContentBase как коллекцию в классе Tag? Я предполагаю, что нет, поскольку он не сможет создать экземпляры этого класса при воссоздании сущности Tag из БД. Я действительно не хочу использовать набор элементов содержимого для каждого типа (например, TaggedBlogPosts, TaggedArticles и т. Д.) В классе Tag.

Единственная причина, по которой я это делаю, заключается в том, что логически элемент контента может иметь много тегов, а один тег может принадлежать нескольким элементам контента. для того чтобы nHibernate управлял связями для меня в таблице сопоставления, я считаю, что мне нужно установить связь «многие ко многим» и добавить тег в коллекцию ContentBase.Tags, а затем элемент контента в коллекцию Tags.TaggedContentItems. до создания таблицы сопоставления в nHibernate.

Вот мои сопоставления для справки:

  <class name="CMS.Core.Model.Tag,CMS.Core" table="bp_Tags">
    <id column="TagName" name="TagName" type="String" unsaved-value="">
      <generator class="assigned" />
    </id>
    <bag name="_taggedContentList" table="bp_Tags_Mappings" inverse="true" cascade="save-update" lazy="true">
      <key column="TagName" />
      <many-to-many class="CMS.Core.Model.ContentBase,CMS.Core" column="Target_Id" />
    </bag>
  </class>

  <class name="CMS.Core.Model.ContentBase,CMS.Core" table="bp_Content">
    <id name="Id" column="Id" type="Int32" unsaved-value="0">
      <generator class="native"></generator>
    </id>
    <property name="SubmittedBy" column="SubmittedBy" type="string" length="256" not-null="true" />
    <property name="SubmittedDate" column="SubmittedDate" type="datetime" not-null="true" />
    <property name="PublishDate" column="PublishDate" type="datetime" not-null="true" />
    <property name="State" column="State" type="CMS.Core.Model.ContentStates,CMS.Core" not-null="true" />
    <property name="ContentType" column="ContentType" type="CMS.Core.Model.ContentTypes,CMS.Core" not-null="true" />

    <bag name="_tagsList" table="bp_Tags_Mappings" lazy="false" cascade="save-update">
      <key column="Target_Id" />
      <many-to-many class="CMS.Core.Model.Tag,CMS.Core" column="TagName" lazy="false" />
    </bag>
    ...
        <joined-subclass name="CMS.Core.Model.BlogPost,CMS.Core" table="bp_Content_BlogPosts" >
          <key column="Id" />
          <property name="Body" type="string" column="Body" />
          <property name="Title" type="string" column="Title" />
        </joined-subclass>
    ...

Ответы [ 2 ]

0 голосов
/ 30 ноября 2009

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

Альтернативой является изменение вашей стратегии на подход «Таблица на класс». Это помещает весь ваш контент в одну таблицу со столбцом дискриминатора для определения типа контента. NHibernate знает, как реализовать каждый тип контента на основе дискриминатора. Недостатком является то, что:

  1. Каждое уникальное свойство конкретных классов должно иметь тип nullable.
  2. Эта таблица может быть громоздкой, если существует множество свойств, специфичных для каждого конкретного класса.

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

Целым отдельным решением было бы сохранить отображение как есть и полагаться на запрос, чтобы получить контент по тегам, не беспокоясь о тегах, хранящих ссылку на коллекцию контента.

0 голосов
/ 30 ноября 2009

Я бы также предположил, что Hibernate потребуется создать экземпляр базового класса, что имеет смысл, поскольку в БД есть данные, непосредственно связанные с ним.

Похоже, что ваши сущности данных находятся в отдельной сборке от вашего основного приложения. Смысл не создания экземпляра базы с точки зрения бизнеса, поэтому, если вы сделаете конструктор internal для сборки Core, это достигнет того, чего вы хотите? Если нет, может быть полезно спросить себя: от кого я защищаю эту функцию?

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