我在两个实体(父和子)之间有父子关系.
我的父映射如下:
<class name="Parent" table="Parents">
...
<bag name="Children" cascade="all">
<key column="ParentID"></key>
<one-to-many class="Child"></one-to-many>
</bag>
</class>
Run Code Online (Sandbox Code Playgroud)
我想执行以下操作:
someParent.Children.Remove(someChild);
Run Code Online (Sandbox Code Playgroud)
Child类具有对另一个父类Type的引用.这种关系看起来像
注意:我为上面的非链接url道歉,我似乎无法使用Markup通过url字符串中的星号
由于这种关系,当调用上面的代码而不是DELETE查询时,会生成一个UPDATE查询,该查询从Child表中删除ParentID(设置为null).
当从Parent.Children集合中删除时,是否可以强制NHibernate完全删除子记录?
UPDATE
@ Spencer的解决方案
非常有吸引力的解决方案,因为这可以在未来的课程中实现.但是,由于在存储库模式中处理会话的方式(在我的特定情况下),这几乎是不可能的,因为我们必须根据应用程序传递会话类型(CallSessionContext/WebSessionContext).
@ Jamie的解决方案
简单快速地实施,但是我遇到了另一个障碍.我的子实体看起来如下:
使用新方法时,NHibernate生成一个更新语句,将TypeID和ParentID设置为null,而不是单个删除.如果我错过了实现中的某些内容,请告诉我,因为这种方法可以轻松推进.
@ 此处描述的One-Shot-Delete解决方案概述了取消引用该集合以强制单个删除的想法.与上述结果相同,但发布了更新声明.
//Instantiate new collection and add persisted items
List<Child> children = new List<Child>();
children.AddRange(parent.Children);
//Find and remove requested items from new collection
var childrenToRemove = children
.Where(c => c.Type.TypeID == 1)
.ToList();
foreach (var c in childrenToRemove) { children.Remove(m); }
parent.Children = null;
//Set persisted collection to new list
parent.Children = Children;
Run Code Online (Sandbox Code Playgroud)
解
进行了一些挖掘,但Jamie的解决方案经过了一些额外的修改.对于未来的读者,基于我上面的班级模型:
类型映射 - Inverse = true,Cascade = all
父映射 - Inverse = true,Cascade = all-delete-orphan
删除Jamie解决方案中描述的方法.这确实会为每个孤立项生成一个删除语句,因此将来可以进行调整,但最终结果是成功的.
不是公开IList<Child>,而是通过方法控制对集合的访问:
RemoveChild(Child child)
{
Children.Remove(child);
child.Parent = null;
child.Type.RemoveChild(child);
}
Run Code Online (Sandbox Code Playgroud)
Type.RemoveChild 看起来类似,但您必须小心,不要将其放入调用彼此的 RemoveChild 方法的无限循环中。
| 归档时间: |
|
| 查看次数: |
4647 次 |
| 最近记录: |