NHibernate Родительские / дочерние осиротевшие записи с веб-сервисом - PullRequest
3 голосов
/ 04 августа 2009

У меня есть веб-сервис, который принимает Invoice, который содержит дочерние элементы LineItem. Затем он обновляет базу данных для создания или обновления счета-фактуры с помощью NHibernate.

Когда счет обновляется, он передается веб-службе вместе со всеми дочерними элементами LineItem, которые у него есть. Добавления и обновления работают отлично. Однако если дочерний элемент LineItem удаляется из ранее сохраненного счета-фактуры потребителем веб-службы и повторно отправляется, этот LineItem фактически не удаляется из базы данных, а вместо этого для его обратной ссылки на родительский объект устанавливается значение NULL. Я использую (пытаюсь использовать) cascade = "all-delete-orphan" без успеха.

Я подозреваю, что проблема может быть связана с характером операции без состояния (сначала у меня нет LineItem в Invoice.LineItemList на стороне веб-службы, а затем удаляю его, а просто получаю список LineItem как они сейчас должны быть). Однако NHibernate достаточно умен, чтобы обнулить столбец обратных ссылок, поэтому я надеюсь, что есть простой способ заставить его удалить эту строку.

Вот сопоставления (упрощенно).

Parent object (Invoice):

<property name="InvoiceNumber" />
        <!-- If inverse="true", InvoiceId is NOT set to NULL and the record remains -->
<bag name="LineItemList" table="lineitems" inverse="false"  cascade="all-delete-orphan">
  <key column="InvoiceId"/>
  <one-to-many 
    class="LineItem"/>
</bag>    

Дочерние объекты (LineItems):

<many-to-one lazy="false" name="Parent" column="InvoiceID" not-null="false"
             class="Invoice,Company.Business"
             />

<property name="LineItemNumber" />
<property name="SalesAmount"/>

Код персистентности веб-службы выглядит следующим образом:

[WebMethod]

публичный счет-фактура (счет-фактура) { // Необходимо перестроить родительские ссылки, см. Блог

foreach (LineItem item in invoice.LineItems)
{
    item.Parent = invoice;
}

using (PersistenceManager pm = new PersistenceManager())
{
    pm.Save<Invoice>(invoice);
}

return invoice; // Return version potentially modified with DB-assigned ID

}

1 Ответ

1 голос
/ 05 августа 2009

Вы правы, это связано с отсоединенным состоянием ваших объектов и является известным ограничением в допуске к производительности, которое NHibernate описывает как не реализованную функцию «сохранения достижимости». Однако вы, конечно, можете легко удалить все LineItems без действительной ссылки на счет, но мне также не нравится это решение. Обычно я использую клиентские объекты для достижения отсутствия состояния, что, конечно, приводит к загрузке счета-фактуры перед манипулированием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...