2010-05-09 3 views
3

Я весь день стуча головой в стол со следующей проблемой Nhibernate.Nhibernate Проблема с отображением одного-на-один с ошибкой ввода дочернего объекта

Каждый банковский счет имеет один (и только один) набор тарифов, связанных с ним. Первичным ключом таблицы банковского счета, BankAccountID также является внешний ключ и первичный ключ в таблице AccountRate.

public class BankAccount 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual string AccountName { get; set;} 
    public virtual AccountRate AccountRate {get;set;} 
} 

public class AccountRate 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual decimal Rate1 { get; set; } 
    public virtual decimal Rate2 { get; set; } 
} 

У меня есть следующие отображения HBM для BankAccount:

<class name="BankAccount" table="BankAccount"> 
<id name ="BankAccountId" column="BankAccountId"> 
    <generator class="foreign"> 
    <param name="property"> 
     AccountRate 
    </param> 
    </generator> 
</id> 
<property name ="AccountName" column="AccountName" /> 
<one-to-one name="AccountRate" class="AccountRate" constrained="true" cascade="save-update"/> 
</class> 

и следующие за AccountRate:

<class name="AccountRate" table="AccountRate"> 
<id name ="BankAccountId" column="BankAccountId"> 
    <generator class="native" /> 
</id> 
<property name ="Rate1" column="Rate1" /> 
<property name ="Rate2" column="Rate2" /> 
</class> 

Существующий объект BankAccount можно прочитать из базы данных без проблем. Однако, когда создается новый BankAccount, оператор insert не работает;

Cannot insert the value NULL into column 'BankAccountId' 

Проблема заключается в том, что сначала создается дочерний объект AccountRate. Поскольку он еще не получил идентификатор из своего родителя, вставка не работает.

Я думаю, что я прав, говоря, что если свойство AccountRate на BankAccount было коллекцией, я мог бы использовать следующее?

Inverse=True 

, чтобы заставить родителя быть вставленным первым.

Может ли кто-нибудь помочь мне с этим? i На самом деле не хочу использовать коллекцию, между этими таблицами существует только однонаправленная связь «один-к-одному».

Благодаря

Пол

ответ

5

Хорошо, я думаю, что исправил проблему. Похоже, что моя проблема - это классическая взаимно-однозначная связь с общедоступными значениями первичного ключа. Ответ был найден хорошим ночным сном, а затем со ссылкой на стр. 192-193 из 'Nhibernate in Action'.

Сначала произошел ряд ошибок, требующих коррекции. Это потребовало изменения как классов, так и файлов HBM.

Во-первых, каждый класс должен содержать свойство другого класса класса, поэтому мне нужно было добавить свойство BankAccount в класс AccountRate.

public class BankAccount 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual string AccountName { get; set;} 
    public virtual AccountRate AccountRate {get;set;} 
} 

public class AccountRate 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual decimal Rate1 { get; set; } 
    public virtual decimal Rate2 { get; set; } 
    Public virtual BankAccount BankAccount {get;set;} 
} 

Я также сделал ошибку в файле BankAccount НВМ, я не должен был бы сделать класс генератора иностранных. Это должно было быть в классе AccountRate. Ограничение также необходимо было удалить из связи «один-к-одному». Новый файл HBM BankAccount выглядит следующим образом.

<class name="BankAccount" table="BankAccount"> 
<id name ="BankAccountId" column="BankAccountId"> 
    <generator class="native"> 
</id> 
<property name ="AccountName" column="AccountName" /> 
<one-to-one name="AccountRate" class="AccountRate" cascade="all"/> 
</class> 

Далее AccountRate HBM нужен класс генератора установлен на внешней, и «один-к-одному» тег добавляется, чтобы завершить отношения между классами.

<class name="AccountRate" table="AccountRate">   
<id name ="BankAccountId" column="BankAccountId">   
    <generator class="foreign"> 
     <param name="property">BankAccount</param> 
    </generator>   
</id>   
<property name ="Rate1" column="Rate1" />   
<property name ="Rate2" column="Rate2" /> 
<one-to-one name="BankAccount" class="BankAccount" constrained="true" />  
</class> 

Спасибо всем, кто нашел время, чтобы посмотреть на эту проблему. Наверное, это часть кривой.

Paul

+0

Подтвердите, что работа выполнена должным образом. – Darius

0

Один быстрый способ обойти это было бы сделать Nullable BankAccountId. NHibernate должен вставить запись в таблицу BankAccount с нулевым идентификатором, а затем обновить идентификатор.

В прошлом я наткнулся на способ сделать его первоначальной вставкой с правильным идентификатором вместо нуля. К сожалению, я не могу за всю жизнь помнить, что я изменил.

 Смежные вопросы

  • Нет связанных вопросов^_^