我正在努力解决一个小问题并开始得出结论,这根本不可能。
我有一个名为Group的表。与大多数这些系统一样,Group有一个ParentGroup和一个Children集合。所以Table Group看起来像这样:
Group
-ID (PK)
-Name
-ParentId (FK)
我使用FNH AutoMappings做了我的映射,但是我必须覆盖默认值:
p.References(x => x.Parent)
.Column("ParentId")
.Cascade.All();
p.HasMany(x => x.Children)
.KeyColumn("ParentId")
.ForeignKeyCascadeOnDelete()
.Cascade.AllDeleteOrphan()
.Inverse();
现在,一般的想法是能够删除一个节点,并且所有它的子节点也被NH删除。因此,删除唯一的根节点应该基本上清除整个表。
我首先尝试使用Cascade.AllDeleteOrphan
,但这仅适用于从子集合中删除项目,而不是删除父项目。
接下来我尝试了ForeignKeyCascadeOnDelete
,因此操作通过on delete cascade
委托给数据库。但是,一旦我这样做,MSSql2008不允许我创建此约束,但失败了:
引入FOREIGN KEY约束 表'组'''FKBA21C18E87B9D9F7' 可能导致循环或多个级联 路径。指定ON DELETE NO ACTION或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY约束。
嗯,那就是我。我想我会循环遍历孩子并逐个删除它们,从而做一个N + 1。如果有人建议如何更优雅,我会渴望听到它。
答案 0 :(得分:1)
我这样做了它并且有效。
public class Node_Map : ClassMap<Node>
{
public Node_Map()
{
References(x => x.Parent, "IdCmsNodeParent");
HasMany(x => x.Childs).AsBag()
.Inverse()
.Cascade.Delete()
.KeyColumn("IdNodeParent");
}
}
但是,如果NHibernate删除它,你将获得N + 1。只有正确的数据库约束才能一次删除它。
如果您想在Sql server 2008中高效地执行此操作,则应使用递归CTE。
检查: