NHibernate один-ко-многим: проблема вставки дочернего элемента - PullRequest
1 голос
/ 11 марта 2011

Вот мой код:

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>

Ответы [ 2 ]

5 голосов
/ 11 марта 2011

Поскольку у вас нет каскада в коллекции Order.Items, он не будет автоматически создавать элемент для вас при сохранении вашего заказа.

Но вы делаете каскад из Item в Order, поэтому когдаВы сохраняете Item, он также будет обновлять Order.

Когда вы указали inverse = "true", вы сказали NHibernate не обновлять свойство "Item.Order" автоматически, и вы будете обрабатывать это вручную.Поэтому ордер никогда не ассоциируется, когда вы добавляете его в коллекцию, поэтому никогда не появляется там после коммита.

Я думаю, вам просто нужно добавить:

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

, и он создастобновить, удалить элементы, которые принадлежат заказам.

РЕДАКТИРОВАТЬ: конечно, каскад идет на сумку, а не узел один ко многим.

2 голосов
/ 11 марта 2011

Попробуйте добавить каскад в ваше отображение заказов:

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