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

发布于 2024-10-21 14:25:39 字数 1482 浏览 5 评论 0原文

这是我的代码:

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

如果我将多端(Items 属性)标记为 inverse="true",则不会引发异常,但它只插入订单!订单项不会插入到数据库中。

如果我调用 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>

Here is my code:

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();
}

If I uncomment the line session.Save(item), it will insert the order and its item. Otherwise, it throw the exception "Unexpected row count: 0; expected: 1".

If I mark the many end (Items property) as inverse="true", no exception will be thrown, but it inserts only the Order! The order item won't be inserted to the DB.

If I call session.Save(item) without calling session.Save(order), it inserts both the order and it's item.

How can I save the order and its order items without calling session.Save(orderItem) but only call session.Save(order) ? Thanks!

Here is my mappings:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

許願樹丅啲祈禱 2024-10-28 14:25:39

由于您在 Order.Items 集合上没有任何级联,因此当您保存订单时,它不会自动为您创建项目。

但是您确实从 Item 级联到 Order,因此当您保存 Item 时,它也会更新 Order。

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

我认为你只需要添加:

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

它将创建、更新、删除属于订单的项目。

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

Because you don't have any cascade on the Order.Items collection, it will not automatically create the item for you when you save your Order.

But you do cascade from Item to Order, so when you save Item, it will also update Order.

When you specified inverse="true" you told NHibernate not to update the "Item.Order" property automatically, and that you will handle that manually. Therefor the Order is never associated when you add it to the collection hence never shows up there after the commit.

I think you just need to add:

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

and it will create, update, delete items that belongs to orders.

EDIT: of course cascade goes on the bag, not the one-to-many node.

素衣风尘叹 2024-10-28 14:25:39

尝试将级联放入您的订单映射中:

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

Try putting the cascade in your Order mapping:

<bag name="Items" cascade="all">
  <key column="CategoryId" />
  <one-to-many class="Core.OrderItem, Core"/>
</bag>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文