NHibernate - Как сопоставить составной идентификатор с родительской дочерней ссылкой - PullRequest
0 голосов
/ 30 марта 2011

у меня есть следующий сценарий (для лучшей иллюстрации, пример очень упрощен) Модель базы данных BAS_COSTCODE ссылается на BAS_CONTEXT. Ключом к этой таблице является составной с COSTCODEID и CONTEXT_FK. CONTEXT_FK ссылается на BAS_CONTEXT. Для построения иерархического дерева у CostCode может быть родительский элемент. По этой причине есть ссылка на таблицу itselfe.

Файл схемы для Context выглядит так:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="dbo" assembly="App.NHibernate.DataObjects" namespace="App.NHibernate.DataObjects">
      <class name="App.NHibernate.DataObjects.Context" table="BAS_CONTEXT" lazy="false" mutable="true" >
        <id name="Id" type="Int16" column="CONTEXTID" >
          <generator class="assigned"/>
        </id>
        <property name="Name" column="NAME" type="String" not-null="true"/>
       </class>
    </hibernate-mapping>

И схема для CostCode выглядит так:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="dbo" assembly="App.NHibernate.DataObjects" namespace="App.NHibernate.DataObjects">
  <class name="App.NHibernate.DataObjects.CostCode" table="CON_COSTCODE" mutable="true" >

    <composite-id name="CompositeId" class="CostCodeId" unsaved-value="any">
      <key-property name="Id" column="COSTCODEID" type="String" />
      <key-many-to-one name="Context" column="CONTEXT_FK" class="Context" lazy="proxy"/>
    </composite-id>

    <many-to-one name="ParentCostCode" class="CostCode" lazy="proxy" insert="true" update="true" >
      <column name="PARENTCOSTCODE_FK"/>
      <column name="CONTEXT_FK"/>
    </many-to-one>

    <property name="Name" column="NAME" type="String"/>
  </class>
</hibernate-mapping>

Если я создаю новую сущность CostCode и запускаю Commit (), я получаю следующее исключение: System.IndexOutOfRangeException: «Недопустимый индекс 13 для этой коллекции SqlParameterCount с счетом = 13.»

Я думаю, что в NHibernate есть проблема со ссылкой ParentCostCode, которая ссылается на родительский объект CostCode. NHIbernate предполагает записать значение в столбец PARENTCOSTCODE_FK и в CONTEXT_FK. В сопоставлении составной идентификатор указывает на CONTEXT_FK, а ParentCostCode указывает на CONTEXT_FK. Таким образом, они «совместно используют» один и тот же столбец, и NHibernate должен только записать значение в столбец PARENTCOSTCODE_FK.

Одним из решений является добавление дополнительного столбца (возможно, PARENTCONTEXT_FK) в таблицу BAS_COSTCODE для представления контекста для родительского объекта. Но я не хочу иметь дополнительный столбец, потому что значения CONTEXT_FK и PARENTCONTEXT_FK должны иметь одинаковое значение, если существует ссылка на родительский объект. И это было бы излишним.

Есть ли лучшие решения для такого рода проблем? Или я не могу запретить дополнительный столбец в BAS_COSTCODE?

Большое спасибо заранее за ваши ответы!

Ответы [ 3 ]

0 голосов
/ 01 апреля 2011

Я думаю, что эта ошибка происходит, потому что у вас один и тот же столбец отображается дважды. CONTEXT_FK

<many-to-one name="ParentCostCode" class="CostCode" lazy="proxy" insert="true" update="true" >
  <column name="PARENTCOSTCODE_FK"/>
  <column name="CONTEXT_FK"/>
</many-to-one>

Вы можете попробовать это решить:

<many-to-one name="ParentCostCode" class="CostCode" lazy="proxy" insert="false" update="false">
0 голосов
/ 01 апреля 2011

Нетрудно использовать несоставной ключ.

<id>
  <generator class="hilo">
     <!-- ... -->
  </generator>
</id>

<property name="CostCode" column="COSTCODEID" unique-key="CostCodeContext"/>

<many-to-one name="Context" >
  <column name="CONTEXT_FK" unique-key="CostCodeContext"> 
</many-to-one> 

<many-to-one name="Parent" class="CostCode">
  <column name="PARENT_FK"/>
</many-to-one>
0 голосов
/ 01 апреля 2011

У нас была похожая проблема, и мы потратили некоторое время на поиск возможных решений.Мы не могли бы найти способ сделать это без избыточного столбца.Это немного уродливо, но вы можете добавить логику в классы моделей, чтобы обеспечить согласованность двух значений.

...