我有一个对象层次结构如下:
根据此处的其他帖子,我将Report.ReportItems映射设置为Inverse,并将CascadeAllDeleteOrphan设置为。这使得当我从对象中删除报表时,它会删除该报表中的ReportItem。
它的做法非常低效。它基本上是Delete ... Where ReportItemID = ?
。
我已经看到了增加批量大小的建议,以防止在太多的往返旅行中完成,但这似乎是一个草率的修复。有没有办法让NHibernate生成这样的查询:
Delete ... Where ReportID = ?
这样它会执行一个查询,删除所有ReportItem而不是每个ReportItem一个语句。
提前致谢。
修改 的
我从一些人那里听说NHibernate不会以标准的QueryOver等方式工作。
我决定开始使用HQL来解决问题。我稍后会使用一些反射来确保没有使用“魔术字符串”。
我有这个想法:
但这不起作用。您可以看到以下代码:
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。关于如何做到这一点的任何提示?
答案 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删除对象列表。