3

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

我有一个名为 Group 的表。与这些系统中的大多数一样,Group 具有 ParentGroup 和 Children 集合。所以表组看起来像这样:

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但这仅适用于删除 Children 集合中的项目,而不是删除父项。

接下来我尝试ForeignKeyCascadeOnDelete通过on delete cascade. 但是一旦我这样做了,MSSql2008 就不允许我创建这个约束,失败了:

在表 'Group' 上引入 FOREIGN KEY 约束 'FKBA21C18E87B9D9F7' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

好吧,对我来说就是这样。我想我会遍历孩子并一一删除它们,从而进行 N+1。如果有人对如何更优雅地做到这一点有建议,我很想听听。

4

1 回答 1

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。

查看:

于 2010-06-05T16:48:28.873 回答