NHibernate 2 FK以一对一的关系相同的PK

时间:2013-04-19 01:42:38

标签: nhibernate nhibernate-mapping

我在信封和交易之间有一对一的关系。我使用主键关联映射它,如下所示:

<class name="Envelope" table="T_ENVELOPE">
    <id name="EnvelopeId" column="ENVELOPE_ID"><generator class="identity"/></id>
    <one-to-one class="Transaction" cascade="all" name="Transaction" />
</class>
<class name="Transaction" table="T_TRANSACTION">
    <id name="TransactionID" column="TRANSACTION_ID" type="long"><generator class="foreign"><param name="property">Envelope</param></generator></id>
    <one-to-one name="Envelope" class="Envelope" constrained="true" />
</class>

这很好用,但我的情况很复杂,因为T_TRANSACTION有2个FK,它们都映射到T_ENVELOPE's PK (ENVELOPE_ID): TRANSACTION_ID(如上所示)和OLD_DEPRECATED_TXN_ID。所以,我在T_ENVELOPE中有2个具有完全相同值(信封的id)的FK。如何使NHibernate保存ENVELOPE_ID不仅在TRANSACTION_ID中,还在OLD_DEPRECATED_TXN_ID中保存?{/ p>

我希望我没有这个要求,但我正在处理遗留代码模式和代码。我知道我也可以这样做:

  1. envelope.Save //这会保存信封和交易的交易ID但不保存OLD_DEPRECATED_TXN_ID
  2. envelope.transaction.old_deprecated_txn_id = envelope.id
  3. envelope.Save 但是,这会导致一次插入和一次更新。我该如何只进行一次插入?
  4. 以下是一个例子:

    T_ENVELOPE
    ----------
    ENVELOPE_ID
    1
    9
    121
    
    T_TRANSACTION
    -------------
    TRANSACTION_ID | OLD_DEPRECATED_TXN_ID
    1|1
    9|9
    121|121
    

1 个答案:

答案 0 :(得分:0)

根据您的要求,您可以:

  1. 编写存储过程以执行插入并配置NHibernate以在映射中使用此过程。在处理遗留数据库和未使用但必须填充的历史字段时,我采用了这种方法

  2. 使用Interceptor。以下内容应该有效。虽然没经过测试!

    public class TransactionEntityInterceptor : EmptyInterceptor
    {
    
    
      public override boolean OnSave(object entity,
                      object id,
                      object[] state,
                      string[] propertyNames,
                      IType[] types)
      {
          if (entity is Transaction)
          {
              Object TransactionID;
              for ( int i=0; i<propertyNames.Length; i++ )
              {
                  if ( "TransactionID" == propertyNames[i] )
                  {
                      TransactionID = state[i];
                      return true
                  }
              }
    
              for ( int i=0; i<propertyNames.Length; i++ )
              {
                  if ( "OLD_DEPRECATED_TXN_ID" == propertyNames[i] )
                  {
                      state[i] = TransactionID;
                      return true;
                  }
              }
              return false;
          }
          else
          {
              return true;
          }
      }
    }