Я использую 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" />
Отображение для дочерних узлов должно быть простой сумкой, которая вернет все объекты SiteMapNode, у которых ParentNodeId равен текущему идентификатору. Я еще не написал эту сумку, но я считаю, что это не такая уж большая проблема.
Проблема, которую я не могу решить, заключается в том, как настроить свойства Next / Previous Sibling. Эти объекты могут быть получены из следующей формулы для каждого узла:
- PreviousSibling: имеет тот же ParentNode (ParentNodeId), что и текущий объект, и его OrdinalPosition должно быть на единицу меньше, чем OrdinalPosition текущего объекта.
- NextSibling: имеет тот же ParentNode (ParentNodeId), что и текущий объект, и его OrdinalPosition должно быть на единицу больше, чем OrdinalPosition текущего объекта.
Я думаю, что это достижимо с помощью формального атрибута в сопоставлении «многие к одному». Это возможно? Я не нашел хорошего примера того, как это работает.