【发布时间】:2011-01-17 14:46:43
【问题描述】:
我在两个实体(Parent 和 Child)之间有父子关系。
我的 Parent 映射如下:
<class name="Parent" table="Parents">
...
<bag name="Children" cascade="all">
<key column="ParentID"></key>
<one-to-many class="Child"></one-to-many>
</bag>
</class>
我想执行以下操作:
someParent.Children.Remove(someChild);
Child 类引用了另一个父类 Type。关系看起来像
注意:对于上面的非链接网址,我深表歉意,我似乎无法使用标记跳过网址字符串中的星号
由于这种关系,当调用上述代码时,会生成一个 UPDATE 查询,该查询从子表中删除 ParentID(设置为 null),而不是 DELETE 查询。
当从 Parent.Children 集合中删除时,是否可以强制 NHibernate 完全删除子记录?
更新
@Spencer 的解决方案
非常有吸引力的解决方案,因为这可以在未来的课程中实现。但是,由于在存储库模式中处理会话的方式(在我的特定情况下),这几乎是不可能的,因为我们必须根据应用程序传递会话类型(CallSessionContext/WebSessionContext)。
@Jamie 的解决方案
实施简单且快速,但我遇到了另一个障碍。我的子实体如下所示:
使用新方法时,NHibernate 会生成一条更新语句,将 TypeID 和 ParentID 设置为 null,而不是直接删除。如果我在实施过程中遗漏了某些内容,请告诉我,因为这种方法可以轻松推进。
@The One-Shot-Delete solution described here,概述了取消引用集合以强制单个删除的想法。结果与上面相同,但是发出了更新语句。
//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;
解决方案
进行了一些挖掘,但 Jamie 的解决方案通过一些额外的修改得以实现。对于未来的读者,基于我上面的类模型:
类型映射 - Inverse = true,Cascade = all
父映射 - Inverse = true, Cascade = all-delete-orphan
删除 Jamie 解决方案中描述的方法。这确实会为每个孤立项生成一个删除语句,因此将来有可能进行调整,但最终结果是成功的。
【问题讨论】:
标签: c# nhibernate