在nHibernate中,我可以将抽象基类映射到集合吗?

时间:2009-11-17 18:20:52

标签: nhibernate many-to-many abstract-class

我正在构建的CMS中有内容项的基类。它目前标记为抽象,因为我只希望实例化派生类。像BlogPost,Article,Photo等派生的类被设置为nHibernate中我的ContentBase类的连接子类。

我正在尝试在此类和Tag类之间建立多对多映射。我想在ContentBase类上有一组标签,在标签类上有一组ContentBase项。

nHibernate是否允许我将抽象的ContentBase类映射为Tag类的集合?我假设没有,因为当从db重构Tag实体时,它无法实例化此类的任何实例。我真的不想在Tag类上使用每种类型的内容项集合(例如TaggedBlogPosts,TaggedArticles等)。

我这样做的全部原因是因为逻辑上,内容项可以有多个标签,1个标签可以属于多个内容项。为了让nHibernate在映射表中管理我的关系,我相信我必须建立一个多对多关联并将Tag添加到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 :(得分:0)

我还假设Hibernate需要实例化基类,这是有意义的,因为数据库中有直接链接到它的数据。

您的数据实体看起来与主应用程序位于不同的程序集中。不实例化基础的观点是从业务的角度来看,所以如果你将构造函数internal设置为核心程序集,那么它能实现你想要的吗?如果没有,问自己可能会有所帮助:我是谁保护这个功能?

答案 1 :(得分:0)

NHibernate应该允许您将抽象类映射为集合,只要您映射抽象类本身(它看起来像你有)。

另一种方法是将策略更改为Table-per-class-hierachy方法。这会将您的所有内容放入具有鉴别器列的单个表中,以定义内容的类型。 NHibernate知道如何基于鉴别器实现每种内容类型。缺点是:

  1. 具体类的每个唯一属性必须是可为空的类型。
  2. 如果每个具体类都有很多属性,那么这个表就会变得难以处理。
  3. table-per-class-hierachy是首选的默认映射策略(根据NHibernate in Action)。我将从该方法开始,并在需要确定时将其修改为table-per-subclass。

    一个完全独立的解决方案是保持映射不变并依赖查询来按标记获取内容,而不必担心标记会保留对内容集合的引用。