2010-07-13 98 views
0

我们有一个非常深的对象图,我们需要一种方法来删除对象图的根,它需要快速发生。我们正在谈论约10-15个表格中的1000行。我们还将所有收藏映射为AllDeleteOrphan。我们跳过NH将执行外键删除,但它实际上执行删除集合中的每个项目。你如何处理这样的情况?NHibernate和级联删除

+0

我没有足够的nhibernate的知识,但我想知道是否(或更可能*为什么*)这不能仅通过SQL中的级联删除来完成? – annakata 2010-07-13 15:02:57

+0

@annakata:它可以,但AllDeleteOrphan具有这样的语义,即当从收集中删除项目时,它将生成删除语句。 – epitka 2010-07-13 15:04:40

+0

是的,我只是不知道我是否相信效率:)如果依赖关系被SQL丢弃,但对象表示在NHibernate中被持久化显然是最终不好的,但如果发生这种情况,我不会当然。基本上,使用nhibernate是否阻止你调用SQL行为? – annakata 2010-07-13 15:15:37

回答

0

我相信你感兴趣的on-delete="cascade"属性;看样映射:

<set name="Children" table="Child" cascade="save-update" lazy="true" inverse="true"> 
     <key column="ParentId" not-null="true" on-delete="cascade" /> 
     <one-to-many class="Child" /> 
    </set> 

在此的几个注意事项:

  1. 这仅适用于关系的逆侧
  2. 您可以使用访问=“没有做到这一点相同的映射“如果它干净地与你的域模型不匹配(如果你使用模式导出生成你的db,这仍然会创建适当的级联删除)

如果你想保持这种行为compl在对象模型中,我建议查看this post,其中讨论了使用收集事件侦听器执行一次性删除操作。

+0

事件监听器方法看起来非常有前途。我们会测试它,看看它的行为如何 – epitka 2010-07-13 17:24:57

2

在你需要做的批量操作的情况下,你可能想直接在服务执行一些HQL/SQL。 ORM工具提供了很多便利,但有时候它更好地直接处理sql。我们有一个类似的情况,我们不得不做一个对象图的深层副本 - 花10分钟休眠,并用我刚才描述的方法2秒...

编辑 - ive想过你的关注“泄露域外的任何信息“,我想你的意思是你不想混淆担忧。通过我描述的方法,您仍然可以正确分离您的疑虑 - 我说过将hql方法放在服务中,但我的意思是可以在DAO中完成。所有持久性代码在一个地方。

在我们的情况,我们花了很多时间试图调整休眠,并设法使其更快。当一个高级分贝家伙告诉我,只是做它在HQL,花了大约4个小时适当测试,以实现它做....你真的应该考虑这种方法来节省时间......

+0

这当然是一个选择,只是不在我们的情况下,因为我们不想泄露域外的任何东西。 – epitka 2010-07-13 17:23:42

+0

@epitka - 我不明白你的意思是“泄漏我们的域名以外的任何东西”。你应该可以直接使用hql来做到这一点,所以你仍然可以在休眠状态下运行。 – hvgotcodes 2010-07-13 18:15:33

+0

我也发现hql通常莫名其妙地更快。有时要快得多 – Alistair 2010-07-14 11:46:42