NHibernate在删除子集合中的对象时会产生多个查询

时间:2012-02-02 03:32:42

标签: nhibernate fluent-nhibernate hql

我有一个对象层次结构如下:

  • 对象
    • 报告
      • 报告项目

根据此处的其他帖子,我将Report.ReportItems映射设置为Inverse,并将CascadeAllDeleteOrphan设置为。这使得当我从对象中删除报表时,它会删除该报表中的ReportItem。

它的做法非常低效。它基本上是Delete ... Where ReportItemID = ?

我已经看到了增加批量大小的建议,以防止在太多的往返旅行中完成,但这似乎是一个草率的修复。有没有办法让NHibernate生成这样的查询:

Delete ... Where ReportID = ?

这样它会执行一个查询,删除所有ReportItem而不是每个ReportItem一个语句。

提前致谢。

修改

我从一些人那里听说NHibernate不会以标准的QueryOver等方式工作。

我决定开始使用HQL来解决问题。我稍后会使用一些反射来确保没有使用“魔术字符串”。

我有这个想法:

  1. 使用HQL批量删除报告项
  2. 告诉会话刷新对象,以便它可以检测到报告项目已消失
  3. 然后告诉会话删除报告,并让它清理剩余的信息
  4. 但这不起作用。您可以看到以下代码:

    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)
    

    我还尝试在执行HQL语句后执行Session.Evict,但NHibernate继续使用缓存来尝试删除ReportItems。关于如何做到这一点的任何提示?

2 个答案:

答案 0 :(得分:0)

如果您的外键已将删除规则设置为级联,那么您可以告诉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>

答案 1 :(得分:0)

经过大量研究后我发现这根本不可能。您可以使用HQL,原始SQL语句或依赖数据库规则来通过强制执行关系来执行删除操作。但是,没有办法告诉NHibernate根据其所有者的ID删除对象列表。