在NHibernate中使用级联

时间:2011-01-16 03:26:36

标签: c# nhibernate cascade

我有两个类,称为Monkey和Banana,具有一对多的双向关系。

Monkey monkey = new Monkey();
Banana banana = new Banana();
monkey.Bananas.Add(banana);
banana.Monkey = monkey;
hibernateService.Save(banana);

当我运行那段代码时,我希望持久化猴子和香蕉。然而,它只是在我明确保存猴子时才持久,反之亦然。最初,这是有道理的,因为只有我的Monkey.hbm.xml具有cascade="all"的映射。

<set name="Bananas" inverse="true" cascade="all">
  <key column="Id"/>
  <one-to-many class="Banana"/>
</set>

我想我只需要将以下内容添加到我的Banana.hbm.xml文件中:

<many-to-one name="Monkey" column="Id" cascade="all" />

不幸的是,当我尝试运行代码段时,这会导致Parameter index is out of range错误。我调查了这个错误并发现this post,但我仍然没有看到我做错了什么。据我所知,我在每一侧都有一次映射关系。有关完整披露,以下是两个映射文件:

Monkey.hbm.xml

<class name="Monkey" table="monkies" lazy="true">
    <id name="Id">
      <generator class="increment" />
    </id>
    <property name="Name" />
    <set name="Bananas" inverse="true" cascade="all">
      <key column="Id"/>
      <one-to-many class="Banana"/>
    </set>
</class>

Banana.hbm.xml

<class name="Banana" table="bananas" lazy="true">
    <id name="Id">
      <generator class="increment" />
    </id>
    <property name="Name" />
    <many-to-one name="Monkey" column="Id" cascade="all" />
</class>

3 个答案:

答案 0 :(得分:3)

参数索引超出范围错误是由于您的映射。您已将Id映射为关系中的主键和外键。

答案 1 :(得分:1)

子映射(Banana)不需要具有cascade属性。如果一个香蕉被删除,猴子可能还有其他香蕉,但是当猴子被改变时,它的所有香蕉应该相应地改变,所以只有猴子需要具有级联属性

答案 2 :(得分:1)

为了将来参考,您还应该包含数据库模式以解决此类问题,因为在不知道模式的情况下验证映射文件可能很困难。

我的猜测是你搞砸了你的外键。你说这个关系是一对多的,所以这意味着Banana有一个猴子表的外键,对吗?此外键列的标准命名是MonkeyID,这在您的映射中似乎缺少 - 所有列名称似乎都是ID。 James Ide在类似的行上回答,然后你说“Id是两个表中主键列的名称。我的关系映射应该是什么样的?” - 实际上,两个表上的主键列名称都是Id非常好,但仍然没有描述关系。正如我上面提到的,你需要一个外键用于关系。

一旦你修复了你的关系,你会发现级联问题会自行解决。人们通常想要从级联中获取的行为是从父级到子级的级联删除,但反之亦然,在这种情况下,您可能希望在多对一元素而不是级联上使用cascade =“save-update” = “所有”。

最后,作为一个无耻的插件,你考虑过尝试Fluent NHibernate吗?您可能会发现它比hbm xml语法更容易学习。