0

我有以下场景(为了更好地说明,示例非常简化) 数据库模型 BAS_COSTCODE 指的是 BAS_CONTEXT。此表的键是 COSTCODEID 和 CONTEXT_FK 的组合。CONTEXT_FK 指的是 BAS_CONTEXT。要构建分层树,CostCode 可以有一个父级。出于这个原因,有一个对表本身的引用。

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:“此 SqlParameterCollection 的索引 13 无效,Count=13。”

我认为 NHibernate 的引用 ParentCostCode 有问题,它指的是父 CostCode 对象。NHIbernate 假定将值写入列 PARENTCOSTCODE_FK 和 CONTEXT_FK。在映射中,composite-id 指向 CONTEXT_FK,ParentCostCode 指向 CONTEXT_FK。因此它们“共享”同一列,NHibernate 应该只向 PARENTCOSTCODE_FK 列写入一个值。

一种解决方案是向表 BAS_COSTCODE 添加一个附加列(可能是 PARENTCONTEXT_FK)来表示父对象的上下文。但我不想有一个额外的列,因为如果存在对父对象的引用,则 CONTEXT_FK 和 PARENTCONTEXT_FK 的值必须具有相同的值。那将是多余的。

这类问题有更好的解决方案吗?或者我不能阻止 BAS_COSTCODE 中的附加列?

非常感谢您的回答!

4

3 回答 3

0

我认为发生此错误是因为您将同一列映射了两次。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">
于 2011-04-01T02:05:35.110 回答
0

使用非复合密钥很简单。

<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>
于 2011-04-01T07:05:51.830 回答
0

我们遇到了类似的问题,并花了一些时间研究可能的解决方案。如果没有多余的列,我们无法找到一种方法来做到这一点。这有点难看,但您可以将一些逻辑放入模型类中以强制两个值的一致性。

于 2011-03-31T23:32:23.530 回答