用NHibernate删除树

时间:2010-06-05 10:11:40

标签: c# .net nhibernate cascading-deletes

我正在努力解决一个小问题并开始得出结论,这根本不可能。

我有一个名为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。如果有人建议如何更优雅,我会渴望听到它。

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。

检查: