3

由于以下 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; }
}

我有以下 BankAccount 的 HBM 映射:

<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 时,插入语句失败:

Cannot insert the value NULL into column 'BankAccountId'

问题似乎是首先创建了子对象 AccountRate 。由于尚未从其 Parent 获得标识符,因此插入失败。

我认为我的说法是正确的,如果 BankAccount 上的 AccountRate 属性是一个集合,我可以使用以下内容吗?

Inverse=True

为了强制先插入父级。

谁能帮我这个?我真的不想使用集合,这些表之间只有单向的一对一关系。

谢谢

保罗

4

2 回答 2

5

好的,我想我已经解决了这个问题。看来我的问题是与共享主键值的经典一对一关联。答案是通过睡个好觉找到的,然后参考 “Nhibernate in Action”的第 192-193 页。

首先有一些错误需要纠正。这需要修改类和 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 HBM 文件中犯了一个错误,我不应该将生成器类设为外部。那应该在 AccountRate 类上。约束也需要从一对一的链接中移除。新的 BankAccount HBM 文件如下。

<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 需要将生成器类设置为 foreign ,并添加一个“一对一”标签来完成类之间的关系。

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

感谢所有花时间研究这个问题的人。我想这都是曲线的一部分。

保罗

于 2010-05-10T11:20:53.677 回答
0

解决此问题的一种快速方法是使 BankAccountId 可以为空。NHibernate 应该在 BankAccount 表中插入一条带有空 id 的记录,然后更新 id。

在过去,我偶然发现了一种让它使用正确的 id 而不是 null 进行初始插入的方法。不幸的是,我一生都记不起我改变了什么。

于 2010-05-09T21:34:44.143 回答