2009-02-23 24 views
0

我使用nHibernate來映射一個非常類似於.NET的System.Web.SiteMapNode的對象。爲了保持我的對象類似於這個.NET對象,我希望它包含一個ParentNode,PreviousSibling,NextSibling和ChildNodes複雜屬性。休眠Next/Previous兄弟映射

表看起來有點像這樣,是開放改變:

  • ID(INT)
  • 標題(字符串)
  • 說明(串)
  • 鍵(串)
  • ParentNodeId(int)
  • OrdinalPosition(int)
  • ReadOnly(bool)
  • 網址(串)

我可能不需要的模仿.NET的SiteMapNode的物品(如isExternal布爾)的一些其他屬性,但我認爲這些都是無關緊要的這個問題。

我當前的映射是這樣的:

<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所有的SiteMapNode對象等於當前的ID。我還沒有寫這個包,但我相信這不是什麼大不了的事。

我似乎無法解決的問題是如何執行Next/Previous兄弟屬性。這個目的可以從下面的公式爲每個節點導出:

  • PreviousSibling:具有相同ParentNode(ParentNodeId)作爲當前對象及其OrdinalPosition應比當前對象的OrdinalPosition少一個。
  • NextSibling:與當前對象具有相同的ParentNode(ParentNodeId),且其OrdinalPosition應該比當前對象的OrdinalPosition多一個。

我認爲這是可以通過多對一映射的形式屬性實現的。這可能嗎?我還沒有找到這個工作原理的一個好例子。

回答

0

我不認爲你要求的是嚴格可行的(儘管如果是這樣的話,我會非常感興趣的看到解決方案)。會有一個相對簡單的解決方法,但NHibernate不支持在許多端使用索引集合的雙向一對多映射。

想到的唯一的東西有點難看:讓父對象爲每個子對象保留自己的索引映射(鍵入OrdinalPosition)。對孩子做這樣的事情:

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

我相信斯圖亞特在這種情況下是正確的。對於多對一的映射是不可能的。如果NHibernate提供了一種方法來處理這個映射,那麼我可能有機會。

另一種可能的解決方案,雖然效率低下,但要創建一個使用字段設置器的包。將是Next/Previous設置的公共屬性仍然會返回對象引用(而不是可枚舉)。在getter中它只會引用該字段中枚舉的第一個位置。延遲加載將是理想的,因爲NHibernate將無法在初始加載對象的情況下加載此對象。每次訪問此對象都會受到懲罰。

我想這兩種解決方案都有類似的懲罰。