【问题标题】:Tree deletion with NHibernate使用 NHibernate 删除树
【发布时间】:2011-02-28 02:59:50
【问题描述】:

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

我有一个名为 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 就不允许我创建这个约束,失败了:

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

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

【问题讨论】:

    标签: c# .net nhibernate cascading-deletes


    【解决方案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。

    检查:

    【讨论】:

    • 但是这样你就不会为孩子和父母使用同一列?您最终得到 2 个 FK 列:IdCmsNodeParent 和 IdNodeParent 应该只有一个。无论如何,感谢您的链接!
    • 呃,对不起。 IdCmsNodeParent 应该是 IdNodeParent。我复制粘贴了我的代码,我想删除单词“Cms”,因为它没有任何信息,但我忘记在引用方法中删除它。
    • 酷。非常感谢。我会试试的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多