NHibernate сопоставление "один к одному", где данные второй таблицы могут быть нулевыми
У меня есть существующая база данных с таблицей Transactions. Я добавил новую таблицу под названием TransactionSequence, где каждая транзакция будет иметь в итоге только одну запись. Мы используем таблицу последовательностей для подсчета транзакций для данной учетной записи. Я сопоставил это как взаимно однозначное отображение, где TransactionSequence имеет первичный ключ TransactionId.
Ограничение заключается в том, что вместо триггера в таблице транзакций нет обновлений отмененных или размещенных транзакций.
Итак, когда последовательность вычисляется и транзакция сохраняется, NHibernate пытается отправить обновление транзакции, например "UPDATE Transaction SET TransactionId =? WHERE TransactionId =? '. Но это не удается из-за триггера. Как настроить отображение, чтобы NHibernate не попытался обновить таблицу транзакций при вставке новой таблицы TransactionSequence?
Отображение транзакций:
<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>
Любая помощь будет принята с благодарностью...
Ответы
Ответ 1
Индивидуальное сопоставление в 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 должен ударить по базе данных, чтобы узнать, существует ли цель. Затем вы можете попробовать сыграть с ограничено = "true/false", чтобы увидеть, можете ли вы убедить его лениво загрузить ассоциацию "один к одному".
В целом, это приведет к полной трате времени.
Я предлагаю либо:
- У вас есть две ассоциации "один-два".
- Имейте ассоциацию "много-к-одному" с коллекцией на другом конце.
Это сэкономит вам много головных болей в долгосрочной перспективе.
Ответ 2
Оказывается, что для моей ситуации лучше всего работало сопоставление <join table>
. Я просто должен был удостовериться, что я сделал свойства, которые пришли со второй таблицы, были типы с нулевым значением, или это сделало бы вставку для сохранения, даже если ничего не изменилось. Поскольку мне не нужна ленивая загрузка для второго стола, это отлично работает. Я уверен, что я мог бы получить парные сопоставления "много-к-одному" для работы, но он не был интуитивным и выглядел более сложным, чем параметр таблицы соединений, однако <join table>
доступен только в NHibernate 2.0 и выше.