Hibernate下一个/上一个兄弟映射

时间:2009-02-23 20:26:17

标签: nhibernate hibernate nhibernate-mapping

我正在使用nHibernate映射一个与.NET的System.Web.SiteMapNode非常相似的对象。为了使我的对象与此.NET对象类似,我希望它包含ParentNode,PreviousSibling,NextSibling和ChildNodes复杂属性。

该表看起来有点像这样,可以更改:

  • ID(int)
  • 标题(字符串)
  • 说明(字符串)
  • 键(字符串)
  • ParentNodeId(int)
  • OrdinalPosition(int)
  • ReadOnly(bool)
  • Url(字符串)

我可能有一些其他属性不需要模仿.NET SiteMapNode对象(比如isExternal bool),但我认为这些对于这个问题无关紧要。

我当前的映射如下所示:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="AthletesCafe.Core.Domain.System.SiteMap" assembly="AthletesCafe.Core">
<class name="SiteMapNode" table="SiteMapNode" lazy="true" >

<id name="ID" type="Int32" unsaved-value="0">
  <column name="ID" not-null="true" unique="true" index="PK_SiteMapNode"/>
  <generator class="identity" />
</id>

<property name="Title" column="Title" type="String" length="255" not-null="true" />
<property name="Description" column="Description" type="String" not-null="false" />

<property name="Url" column="Description" type="String" not-null="true"  />

<property name="SiteMapKey" column="SiteMapKey" type="String" not-null="true" length="255"  />

<property name="OrdinalPosition" column="OrdinalPosition" type="Int32" not-null="true" />

<property name="ReadOnly" column="ReadOnly" not-null="true" type="System.Boolean" />

<property name="IsExternal" column="IsExternal" not-null="true" type="System.Boolean" />

<many-to-one name="ParentNode" column="ParentNodeId" class="AthletesCafe.Core.Domain.System.SiteMap.SiteMapNode, AthletesCafe.Core" 
             access="field.pascalcase-underscore" not-null="false" />
<many-to-one name="PreviousNode" column="ParentNodeId" class="EatMyTrainer.Core.Domain.SiteMap.SiteMapNode, EatMyTrainer.Core" not-null="false" /></hibernate-mapping>

ParentNode映射很简单,因为它应该只是一个简单的多对一映射。这是我的代码(未经测试,但我认为是正确的):

<many-to-one name="ParentNode" column="ParentNodeId" class="AthletesCafe.Core.Domain.System.SiteMap.SiteMapNode, AthletesCafe.Core" 
             access="field.pascalcase-underscore" not-null="false" />

子节点的映射应该只是一个简单的包,它将带回所有ParentNodeId等于当前ID的SiteMapNode对象。我还没有写过这个包,但我认为这不是什么大问题。

我似乎无法解决的问题是如何执行Next / Previous Sibling属性。可以从每个节点的以下公式派生此对象:

  • PreviousSibling:与当前对象具有相同的ParentNode(ParentNodeId),其OrdinalPosition应比当前对象的OrdinalPosition少一个。
  • NextSibling:具有与当前对象相同的ParentNode(ParentNodeId),其OrdinalPosition应该比当前对象的OrdinalPosition多一个。

我认为这可以通过多对一映射的表格属性来实现。这可能吗?我还没有找到一个如何运作的好例子。

2 个答案:

答案 0 :(得分:0)

我不认为你所要求的是严格可能的(尽管如果有的话,我会非常有兴趣看到解决方案)。会有一个相对简单的解决方法,但NHibernate不支持在许多端使用索引集合的双向一对多映射。

唯一想到的是有点难看:让父对象将自己的索引映射(键入OrdinalPosition)保存到每个子对象。在孩子身上做了类似的事情:

public SiteMapNode NextSibling()
{
    return this.Parent.NextSibling(this);
}

答案 1 :(得分:0)

我认为斯图尔特在这种情况下是正确的。对于多对一映射是不可能的。如果NHibernate提供了一种方法来处理这个映射,那么我可能有机会。

另一种可能的解决方案虽然效率低下,但是创建一个使用字段设置器的包。将是Next / Previous设置的公共属性仍将返回对象引用(而不是可枚举)。在getter中,它只会引用字段中可枚举的第一个位置。延迟加载是理想的,因为NHibernate无法在初始加载对象的情况下加载此对象。每次访问此对象都会受到惩罚。

我猜两种解决方案都有类似的惩罚。