NHibernate производит несколько запросов на удаление объекта в дочерней коллекции - PullRequest
2 голосов
/ 02 февраля 2012

У меня есть иерархия объектов следующим образом:

  • Объект
    • Отчеты
      • Элементы отчета

Основываясь на других сообщениях здесь, я установил сопоставление Report.ReportItems в значение Inverse и CascadeAllDeleteOrphan. Это делает так, что когда я удаляю Report из Object, он удаляет ReportItems в этом отчете.

То, как это происходит, очень неэффективно. Это в основном делает Delete ... Where ReportItemID = ?.

Я видел предложения увеличить размер пакета, чтобы предотвратить это в слишком большом количестве циклов, но это похоже на неаккуратное исправление. Есть ли способ заставить NHibernate генерировать такой запрос вместо этого:

Delete ... Where ReportID = ?

Таким образом он будет выполнять один запрос, который удалит все элементы ReportItems вместо одного оператора на элемент ReportItem.

Заранее спасибо.

Редактировать

Я слышал от нескольких людей, что NHibernate просто не будет работать таким образом со стандартным QueryOver и т. Д.

Я решил начать использовать HQL, чтобы исправить проблему. Позже я воспользуюсь отражением, чтобы убедиться, что «магические струны» не используются.

У меня была идея:

  1. Использование HQL для массового удаления элементов отчета
  2. Скажите сеансу обновить объект, чтобы он мог обнаружить, что элементы отчета пропали
  3. Затем скажите сеансу стереть отчет, и пусть он очистит оставшуюся информацию

Это не работает, хотя. Вы можете увидеть код ниже:

Session.CreateQuery("delete ReportItem r where r.Report= :report").SetEntity("report", SelectedReport).ExecuteUpdate()
Session.Refresh(SelectedReport)
Object.Reports.Remove(SelectedReport)
Session.Delete(SelectedReport)
Session.Update(Object)

Я также пытался сделать Session.Evict после выполнения операторов HQL, но NHibernate продолжает использовать кеш для попытки удаления элементов ReportItems. Любые советы, как это сделать?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2012

После долгих исследований я обнаружил, что это просто невозможно.Вы можете использовать HQL, необработанные операторы SQL или полагаться на правила базы данных для выполнения удалений путем установления взаимосвязи.Однако нет способа указать NHibernate удалить список объектов на основе идентификатора их владельца.

0 голосов
/ 05 февраля 2012

Если ваш внешний ключ имеет правило удаления, установленное в каскад, то вы можете указать NH не генерировать операторы DELETE для дочерних элементов при удалении родительского элемента. В этом случае NH сгенерирует оператор DELETE только для родительского объекта.

<bag name="ReportItems" cascade="all-delete-orphan" inverse="true">
    <key column="report_id" on-delete="cascade" />
    <one-to-many class="ReportItem" />
</bag>
...