NHibernate一对多映射:插入子项问题

时间:2011-03-11 13:32:21

标签: c# .net nhibernate one-to-many

这是我的代码:

Order order = new Order { ... };
OrderItem item = new OrderItem { ... };
order.Items.Add(item);
item.Order = order;

using(var tran = session.BeginTransaction()) {
    session.Save(order);
    // Without this, an exception will be thrown: Unexpected row count: 0; expected: 1
    // session.Save(item);

    tran.Commit();
}

如果我取消注释行session.Save(item),它将插入订单及其商品。否则,它抛出异常“意外的行数:0;预期:1”。

如果我将many end(Items属性)标记为inverse =“true”,则不会抛出任何异常,但它只插入Order!订单商品不会插入数据库。

如果我在不致电session.Save(item)的情况下致电session.Save(order),则会同时插入订单及其商品。

如何在不调用session.Save(orderItem)的情况下保存订单及​​其订单商品,但只能调用session.Save(order)?谢谢!

这是我的映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Core" assembly="Core">
  <class name="Order" table="[Order]">
    <id name="Id">
      <generator class="assigned" />
    </id>

    <property name="Name" />
    <bag name="Items">
      <key column="CategoryId" />
      <one-to-many class="Core.OrderItem, Core"/>
    </bag>
  </class>

  <class name="OrderItem">
    <id name="Id">
      <generator class="assigned" />
    </id>
    <property name="Title" />
    <many-to-one name="Order" column="OrderId" cascade="save-update" not-null="true" />
  </class>

</hibernate-mapping>

2 个答案:

答案 0 :(得分:5)

因为您在Order.Items集合中没有任何级联,所以在您保存订单时它不会自动为您创建项目。

但是你从Item到Order进行级联,所以当你保存Item时,它也会更新Order。

当你指定inverse =“true”时,你告诉NHibernate不要自动更新“Item.Order”属性,并且你将手动处理它。因此,当您将订单添加到集合时,订单永远不会关联,因此在提交后永远不会显示订单。

我认为你只需要添加:

<bag name="Items" cascade="all">

它将创建,更新,删除属于订单的商品。

编辑:当然级联是在包,而不是一对多节点。

答案 1 :(得分:2)

尝试将级联放在订单映射中:

<bag name="Items" cascade="all">
  <key column="CategoryId" />
  <one-to-many class="Core.OrderItem, Core"/>
</bag>