我正在使用nHibernate映射一个与.NET的System.Web.SiteMapNode非常相似的对象。为了使我的对象与此.NET对象类似,我希望它包含ParentNode,PreviousSibling,NextSibling和ChildNodes复杂属性。
该表看起来有点像这样,可以更改:
我可能有一些其他属性不需要模仿.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属性。可以从每个节点的以下公式派生此对象:
我认为这可以通过多对一映射的表格属性来实现。这可能吗?我还没有找到一个如何运作的好例子。
答案 0 :(得分:0)
我不认为你所要求的是严格可能的(尽管如果有的话,我会非常有兴趣看到解决方案)。会有一个相对简单的解决方法,但NHibernate不支持在许多端使用索引集合的双向一对多映射。
唯一想到的是有点难看:让父对象将自己的索引映射(键入OrdinalPosition)保存到每个子对象。在孩子身上做了类似的事情:
public SiteMapNode NextSibling()
{
return this.Parent.NextSibling(this);
}
答案 1 :(得分:0)
我认为斯图尔特在这种情况下是正确的。对于多对一映射是不可能的。如果NHibernate提供了一种方法来处理这个映射,那么我可能有机会。
另一种可能的解决方案虽然效率低下,但是创建一个使用字段设置器的包。将是Next / Previous设置的公共属性仍将返回对象引用(而不是可枚举)。在getter中,它只会引用字段中可枚举的第一个位置。延迟加载是理想的,因为NHibernate无法在初始加载对象的情况下加载此对象。每次访问此对象都会受到惩罚。
我猜两种解决方案都有类似的惩罚。