流畅的NHibernate一对多级联删除

pre*_*sto 4 c# fluent-nhibernate

我已经看到了很多这个问题,但没有一个解决方案对我有用.

我在C#中使用流畅的NHibernate映射到MS SQL的一对多关系.当我尝试删除子元素时,NHibernate尝试通过设置当前NULL抛出错误的外键来实现.

类似问题的解决方案已添加InverseHasMany父级的映射中.但是现在有这个问题:

var parent = //something
parent.Children.Clear();
session.Update(parent);
Run Code Online (Sandbox Code Playgroud)

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

Kei*_*thS 11

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

缺点是,通过将父和子之间的关系指定为反向,NH将关系的"一"侧(父)视为在关系的上下文之外不存在的一方.所以,当你清除所有的孩子时,现在没有孩子的父母是"孤儿",NH会删除它.

这听起来不像你想要的; 所以,我会从这种关系中删除反向映射,允许父母与其子女"拥有"这种关系.删除所有孩子,他们成为孤儿和删除,但父母仍在.现在,你有一个问题,即儿童不能被"孤儿",因为外键不可为空; 他们必须属于某种东西.如果您要使用"孤儿删除"级联规则,NH要求子记录的FK可以为空.这是因为孤立删除是一种双遍操作,需要通过将其FK字段设置为null来使记录首先成为孤立状态.然后,NH将运行第二个语句,以从表中删除任何具有NULL FK的记录.因此,即使使用可空的FK字段,通过使用具有所需级联规则的NH,您将不会有任何具有空FK的记录超过一个过渡期.

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

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

   parent.Children.Clear();
   session.Update(parent);
Run Code Online (Sandbox Code Playgroud)