【问题标题】:NHibernate One-To-Many Delete Not CascadingNHibernate 一对多删除不层叠
【发布时间】:2011-06-13 00:23:18
【问题描述】:

我有一个“照片”类和一个“评论”类。一张照片可以分配有多个 cmets。

我在我的 HBM 映射文件中将此配置为一对多关系,并针对 Photo.hbm.xml 映射文件中的“评论”包设置了 cascade="all-delete-orphan"。

但是,如果我尝试删除具有 1 个或多个相关评论的照片,我会收到“DELETE 语句与 REFERENCE 约束“FK_Comments_Photos”冲突”

我针对 Photo.hbm.xml 中的 Comments 包尝试了其他几个级联选项,但无论我将其设置为什么,我每次都得到相同的结果。我只是希望能够删除照片并让任何关联的 cmets 也自动删除。

这是我的照片映射(为简洁而编辑):

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" .... default-access="property" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="Photo" table="Photos">
    <id name="PhotoId" unsaved-value="0">
        <column  name="PhotoId" />
        <generator class="native" />
    </id>
    ...
    <bag name="Comments" table="Comments" cascade="all-delete-orphan" order-by="DateTimePosted desc" where="Approved=1">
        <key column="PhotoId" />
        <one-to-many class="Comment" />
    </bag>
</class>

这是我的评论映射(为简洁而编辑):

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" ... default-access="property" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="Comment" table="Comments">
    <id name="CommentId" unsaved-value="0">
        <column name="CommentId"></column>
        <generator class="native" />
    </id>
    ...
    <property name="Author" not-null="true" />
    <property name="Body" not-null="true" />
    <property name="Approved" not-null="true" />
    <many-to-one name="Photo" not-null="true">
        <column name="PhotoId" />
    </many-to-one>
</class>

对于我尝试删除带有关联的 cmets 的照片时为什么没有发生级联的原因,有人有任何建议吗?

更新:我可以让级联发生的唯一方法是在 SQL Server 中配置“删除规则”来反对这种与“级联”的关系,这样做意味着我不会'不需要在我的 NHibernate 映射中指定任何级联操作。然而,这对我来说并不理想——我希望能够在理想情况下配置 NHibernate 映射中的级联行为,所以我仍然很困惑为什么它似乎没有注意到我的 NHibernate级联设置?

【问题讨论】:

    标签: asp.net nhibernate relational-database cascading-deletes nhibernate-cascade


    【解决方案1】:

    在您的映射的包集合上尝试使用inverse="true"

    【讨论】:

    • 我也尝试过(当时没有其他方法),但不幸的是没有成功。
    【解决方案2】:

    我的猜测是问题出在 Comment 映射中的多对一设置为 not-null="true"。 因此,NHibernate 在删除 Photo 对象之前不允许将此属性临时设置为 null,因此当删除 Photo 对象时 SQL Server 会引发外键异常。

    如果我没记错删除时的操作顺序是:

    1. 在所有子对象中将外键值设置为 null
    2. 删除父对象
    3. 删除所有子引用

    尝试从多对一中删除 not-null="true" 看看会发生什么。

    【讨论】:

    • 感谢您的建议。我刚试过这个,但仍然是同样的问题/错误消息。如果我删除 SQL Server 中的现有关系/约束,则删除照片记录时不会出现任何错误,但会将我的孤立相关评论记录留在数据库中。就像它只关注 SQL Server 中的配置方式,而忽略 SQL Server 之外的任何级联设置。
    • 你肯定需要删除 not-null="true" 然后添加 Felice 建议的 inverse="true" 无论如何它确实需要,最后离开 cascade="all-delete-orphan ”。我不会弄乱 SQL 服务器,因为你在那里做的事情与 NHibernate 需要做的事情无关。是的,如果在 SQL Server 中添加级联删除可以提供帮助,但这是一个可以通过正确配置实体映射文件完全解决的问题。因此,如果我是你,我会从服务器中删除 SQL 约束,然后使用上述映射文件的建议重试。
    • 感谢您提供额外信息 tolism7。好的,我已经删除了所有 SQL Server 约束,从多对一中删除了 not-null="true" 并在包上添加了 inverse="true",但是当我删除照片时,它仍然会留下孤立的评论数据库:(
    • 我想知道它是否只留下不满足 where="Approved=1" 子句的 cmets。您是否尝试过删除这个以查看效果如何?更好的是,您是否使用过 SQL Profiler 或 NProf 来查看是否为 cmets 触发了删除语句?
    • 啊哈!删除 WHERE 子句确实对其进行了排序!评论记录现在会自动删除。谢谢!至少我现在明白哪里出了问题。现在我想我需要弄清楚如何绕过 WHERE 子句。
    【解决方案3】:

    我有类似的问题 1 天.. 并为此感到沮丧。

    最终解决方案归结为数据库。 我不得不更改“插入更新规范”中的 FK 键约束 “删除规则”:从“无操作”到“级联”

    此外,您还可以设置 “更新规则”:从“无操作”到“级联”

    【讨论】:

      【解决方案4】:

      可以在 NH 中指定 delete-cascade 选项:

      <bag name="Comments" cascade="all-delete-orphan" order-by="DateTimePosted desc" where="Approved=1">
          <key column="PhotoId" on-delete="cascade"/>
          <one-to-many class="Comment" />
      </bag>
      

      你可能应该把它倒过来。然后我想知道你的 FK_Comments_Photos 列是在哪里指定的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-14
        • 1970-01-01
        相关资源
        最近更新 更多