【问题标题】:Nhibernate efficient cascade deleteNhibernate高效级联删除
【发布时间】:2019-02-25 18:28:16
【问题描述】:

在使用 nHibernate 的删除上下文中,当删除具有子集合的父级时 我想知道为什么 Nhibernate 为孩子逐行删除(在孩子 PK 上)

DELETE FROM children where Id=1
DELETE FROM children where Id=2
...    
DELETE FROM parent where id=1

为什么nhibernate不能做

DELETE FROM children where parentId=1
DELETE FROM parent where id=1

例如,如果父母有 10 万个孩子,效率会更高。 我搜索了许多主题而没有找到正确的答案。我也做了一些测试,但没有成功 一个想法?

【问题讨论】:

    标签: nhibernate sql-delete nhibernate-cascade


    【解决方案1】:

    在这种情况下,我们可以使用 NHibernate 扩展点。文档

    19.3. Custom SQL for create, update and delete

    NHibernate 可以使用自定义 SQL 语句进行创建、更新和 删除操作。 NHibernate 中的类和集合持久化器 已经包含一组配置时间生成的字符串 (insertsql、deletesql、updatesql 等)。映射标签<sql-insert>, <sql-delete><sql-update> 覆盖这些字符串:

    <class name="Person">
        <id name="id">
            <generator class="increment"/>
        </id>
        <property name="name" not-null="true"/>
        <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
        <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
        <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
    </class>
    

    所以,如果标准删除没有用,我们可以提供自己的过程,包括一些存储过程

    <sql-delete>exec deletePerson ?</sql-delete>
    

    总结,在大多数情况下,标准模型足够有效。如果我们需要改进 SQL .. 我们可以 ...

    【讨论】:

    • 我看到了这个解决方案,但它破坏了逻辑域模型。如果您在删除实体之前有一些逻辑,则可能需要在您的存储过程中复制它。 casade 也有同样的问题;在这种情况下,您需要在数据库上定义您的级联(所以我们现在在 2 个地方定义了级联...... hbm 和数据库)
    • 这只是一个扩展点..您可以在此处添加删除逻辑..如果您想优化..但您可以使用其他地方...例如您可以引入事件侦听器(在此处查看stackoverflow.com/q/21838758)并使用 C# 挂钩删除...关键是 - 基本删除在那里,工作,也许不是最有效的.. 你确实有地方,你可以覆盖默认值..希望对您有所帮助;)
    • 实际上我使用存储过程和 HQL。我没有选择,因为如果我让 nhibernate 做他自己的事情,它就会超时。我想了解为什么它不能被 nhibernate 正确(或更有效地)管理
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多