11

我有一个现有的数据库,其中包含表 Transactions。我添加了一个名为 TransactionSequence 的新表,其中每个事务最终只有一条记录。我们正在使用序列表来计算给定帐户的交易。我已将其映射为一对一映射,其中 TransactionSequence 具有 TransactionId 的主键。

约束是事务表上有一个代替触发器不允许更新已取消或已发布的事务。

因此,当计算序列并保存事务时,NHibernate 会尝试发送事务更新,例如 'UPDATE Transaction SET TransactionId = ? WHERE TransactionId = ?'。但是由于触发器,这失败了。如何配置我的映射,以便 NHibernate 在插入新的 TransactionSequence 表时不会尝试更新 Transaction 表?

事务映射:

<class name="Transaction" table="Transaction" dynamic-update="true" select-before-update="true">
    <id name="Id" column="ID">
        <generator class="native" />
    </id>

    <property name="TransactionTypeId" access="field.camelcase-underscore" />
    <property name="TransactionStatusId" column="DebitDebitStatus" access="field.camelcase-underscore" />

    <one-to-one name="Sequence" class="TransactionSequence" fetch="join"
                 lazy="false" constrained="false">      
    </one-to-one>
</class>

和序列映射:

<class name="TransactionSequence" table="TransactionSequence" dynamic-update="true">
    <id name="TransactionId" column="TransactionID" type="Int32">
        <generator class="foreign">
            <param name="property">Transaction</param>
        </generator>
    </id>

    <version name="Version" column="Version" unsaved-value="-1" access="field.camelcase-underscore" />

    <property name="SequenceNumber" not-null="true" />

    <one-to-one name="Transaction" 
                class="Transaction" 
                constrained="true" 
                foreign-key="fk_Transaction_Sequence" />

</class>

任何帮助将不胜感激...

4

2 回答 2

15

nhibernate 中的一对一映射并不像你想象的那样工作。它的设计目的是让您有两个类,当它们持久保存到它们相应的表时,它们具有相同的主键。

但是你可以让它工作,但它并不漂亮。我将向您展示如何提供一些替代方案:

在您的事务 hbml 中:

<one-to-one name="Sequence" class="TransactionSequence" property-ref="Transaction"/>

在您的序列 html 中:

<many-to-one name="Transaction" class="Transaction" column="fk_Transaction_Sequence" />

应该做你想做的事。注意属性-ref。

您要发布的下一个问题将询问您如何在一对一关联上进行延迟加载。答案是,你不能……你可以,但它可能行不通。问题是您在序列表上有外键,这意味着 nhibernate 必须访问数据库以查看目标是否存在。然后你可以试着玩一下 constrained="true/false" 看看你能不能说服它懒加载一对一的关联。

总而言之,这将完全浪费您的时间。

我建议:

  1. 有两个多对一关联。
  2. 与另一端的集合具有多对一关联。

从长远来看,这将为您省去很多麻烦。

于 2008-10-28T21:05:03.860 回答
2

事实证明,对于我的情况,<join table>映射效果最好。我只需要确保来自第二个表的属性是可为空的类型,否则即使没有任何更改,它也会在保存时插入。由于第二个表不需要延迟加载,因此效果很好。我确信我可以得到配对的多对一映射来工作,但它并不直观,而且看起来比连接表选项更复杂,但<join table>仅在 NHibernate 2.0 及更高版本中可用。

于 2008-10-29T12:58:52.717 回答