【问题标题】:Fluent NHibernate One-to-Many Cascade DeleteFluent NHibernate 一对多级联删除
【发布时间】:2013-11-14 03:16:32
【问题描述】:

我经常看到这个问题,但没有一个解决方案对我有用。

我在 C# 中使用流利的 NHibernate 映射到 MS SQL 的一对多关系。当我尝试删除子元素时,NHibernate 尝试通过将外键设置为 NULL 来执行此操作,这当然会引发错误。

类似问题的解决方案是将Inverse 添加到父级的HasMany 映射中。但是现在出现了这个问题:

var parent = //something
parent.Children.Clear();
session.Update(parent);

这会导致整个父级被删除!为什么?

【问题讨论】:

    标签: c# fluent-nhibernate


    【解决方案1】:

    在映射中使用“反向”颠倒了谁“拥有”父子关系的概念。通过指定“Inverse”,NH 基本上就像关系的 Child 端决定它是否属于 Parent,而不是 Parent 决定它是否具有 Child。一个很好的现实世界的例子是学生被大学录取。学生可以选择不再属于学院,并且仍然可以作为一个实体存在并具有意义。也是学生,而不是学院,是决定是否与学院建立或切断这种关系的主要决定者(在现实生活中,是的,在某些情况下,学院说不再欢迎学生,但大学不只是告诉信誉良好的学生“你要辍学了”;是学生告诉大学的)。

    简而言之,通过将 Parent 和 Children 之间的关系指定为 Inverse,NH 将关系的“一”侧(Parent)视为不能存在于关系上下文之外的一侧。因此,当您清除所有子项时,现在没有子项的父项是“孤立的”,NH 将其删除。

    这听起来不像你想要的;所以,我会从这个关系中删除逆映射,允许父级与其子级“拥有”这个关系。删除所有子项,它们将成为孤儿并被删除,但父项仍然存在。现在,您遇到的问题是,子项不能“孤立”,因为外键不可为空;他们必须属于某物。如果您要使用“孤立删除”级联规则,NH 要求子记录的 FK 可以为空。这是因为孤立删除是一个两遍操作,需要首先孤立记录,方法是将其 FK 字段设置为空。然后 NH 将运行第二条语句以从表中删除任何具有 NULL FK 的记录。因此,即使使用可为空的 FK 字段,通过将 NH 与所需的级联规则一起使用,您将不会有任何具有空 FK 的记录超过一个短暂的时期。

    如果这是不可接受的,您将不得不从级联规则中删除孤立删除,并手动删除每条记录并将其从会话中删除。

    foreach(var child in parent.Children)
          session.Delete(child);
    
       parent.Children.Clear();
       session.Update(parent);
    

    【讨论】:

    • 感谢您 - 您反馈中的此信息解决了我的问题 - “如果您要使用“孤立删除”级联规则,NH 要求子记录的 FK 可以为空。”
    • (进一步到上面)...我无法删除我的子记录,因为我的子表中的 FK 设置为 NOT NULL 并且删除引发了“列不能包含空值”,因为正如您所说,NH 执行 2 次删除子代 - 首先将子代设置为 NULL,然后在 FK = null 处删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多