2008-10-28 8 views
11

J'ai une base de données existante avec la table Transactions en elle. J'ai ajouté une nouvelle table appelée TransactionSequence où chaque transaction aura finalement un seul enregistrement. Nous utilisons la table de séquence pour compter les transactions pour un compte donné. J'ai mappé cela comme un mappage un-à-un où TransactionSequence a une clé primaire de TransactionId.NHibernate mappage un-à-un où les données de la deuxième table peuvent être nul

La contrainte est qu'il existe un au lieu de déclencheur sur la table de transactions ne permet pas les mises à jour des transactions annulées ou postées. Ainsi, lorsque la séquence est calculée et que la transaction est enregistrée, NHibernate essaie d'envoyer une mise à jour de la transaction comme 'UPDATE Transaction SET TransactionId =? OERE TransactionId =? '. Mais cela échoue à cause du déclencheur. Comment puis-je configurer mon mappage afin que NHibernate n'essaie pas de mettre à jour la table Transaction lorsqu'une nouvelle table TransactionSequence est insérée?

mapping 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> 

Et la mise en correspondance de séquence:

<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> 

Toute aide serait grandement appréciée ...

Répondre

15

Un à un mapping NHibernate ne fonctionne pas comme vous le pensez. Il est conçu pour que vous ayez deux classes qui, lorsqu'elles sont conservées dans leurs tables correspondantes, ont les mêmes clés primaires. Cependant, vous pouvez le faire fonctionner, mais ce n'est pas joli. Je vais vous montrer comment puis offrir quelques alternatives:

dans votre transaction hbml:

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

Dans votre html séquence:

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

Ce devrait faire ce que vous voulez qu'il faire. Notez la propriété-ref.

La prochaine question que vous allez poser sur va demander comment vous obtenez le chargement paresseux sur les associations one-to-one. La réponse est, vous ne pouvez pas ... bien vous pouvez, mais cela ne fonctionnera probablement pas. Le problème est que vous avez votre clé étrangère sur la table de séquence, ce qui signifie que nhibernate doit frapper la base de données pour voir si la cible existe. Ensuite, vous pouvez essayer de jouer avec contraint = "true/false" pour voir si vous pouvez le persuader de charger paresseusement l'association one-to-one. Dans l'ensemble, il en résultera une perte totale de temps.

Je suggère soit:

  1. ont deux many-to-one.
  2. Avoir une association plusieurs-à-un avec une collection à l'autre extrémité.

Cela vous permettra d'économiser beaucoup de maux de tête à long terme.

+0

Avez-vous un exemple d'utilisation de 2 associations 'many-to-one'? Car l'un d'entre eux doit utiliser la clé étrangère de l'autre table. –

2

Il s'avère que pour ma situation, une cartographie <join table> a fonctionné le mieux.Je devais juste m'assurer que les propriétés provenant de la deuxième table étaient des types Nullable, ou bien faire un insert sur save même si rien n'avait changé. Comme je n'avais pas besoin de chargement paresseux pour la deuxième table, cela fonctionne très bien. Je suis sûr que j'aurais pu coupler des mappings plusieurs-à-un pour travailler, mais ce n'était pas intuitif et semble plus compliqué que l'option de table de jointure, cependant <join table> est seulement disponible dans NHibernate 2.0 et plus.

Questions connexes