我在两个实体(父级和子级)之间有父子关系。

我的父级映射如下:

<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);

子类具有对另一个父类Type的引用。关系看起来像

注意:我为上面的非链接网址道歉,我似乎无法使用Markup跳过网址字符串中的星号

由于这种关系,当调用上面的代码时,将生成一个UPDATE查询而不是DELETE查询,该查询从Child表中删除ParentID(设置为null)。

当从Parent.Children集合中删除时,是否可以强制NHibernate完全删除子记录?

更新

@Spencer的解决方案

非常有吸引力的解决方案,因为这可以在以后的类(class)中实现。但是,由于在存储库模式中处理 session 的方式(在我的特定情况下),这几乎是不可能的,因为我们必须根据应用程序传递 session 类型(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;

解决方案

进行了一些挖掘,但杰米的解决方案进行了一些其他修改。对于 future 的读者,基于上面的我的类(class)模型:

类型映射-逆=真,级联=全部

父级映射-逆= true,级联=全部删除/孤立

删除Jamie解决方案中描述的方法。这确实为每个孤立项目生成了一条delete语句,因此将来有可能进行调整,但是最终结果是成功的。

最佳答案

无需公开IList<Child>,而是通过一种方法来控制对集合的访问:

RemoveChild(Child child)
{
    Children.Remove(child);
    child.Parent = null;
    child.Type.RemoveChild(child);
}

Type.RemoveChild看起来很相似,但是您必须注意不要将其放入调用彼此的RemoveChild方法的无限循环中。

关于c# - 从集合中删除项目(NHibernate),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2276705/

10-16 03:39
查看更多