如何在自引用关系上设置级联?

时间:2013-09-09 15:45:01

标签: c# asp.net-mvc entity-framework asp.net-mvc-4 entity-framework-5

我有默认情况,您自己CategoryRootCategoryChildCategories。如何指定我的流畅模型构建器以在删除时级联所有子类别?

模型

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual Category RootCategory { get; set; }
    public virtual ICollection<Category> ChildCategories { get; set; }
    public virtual ICollection<Item> Items { get; set; }
}

我尝试了什么

我尝试使用流畅的模型构建器,但是当我尝试更新数据库时,这个会出错。

  

引入FOREIGN KEY约束   桌上有'FK_dbo.Categories_dbo.Categories_RootCategory_Id'   “类别”可能会导致循环或多个级联路径。指定ON   DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY   约束

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Category>().HasOptional(x => x.RootCategory).WithMany(x => x.ChildCategories).WillCascadeOnDelete(true);
}

3 个答案:

答案 0 :(得分:4)

我遇到了同样的问题。关于流畅的API配置,我不知道你是否可以在那里做到。你可以做的是将WillCascadeOnDelete设置为false,然后自己删除ChildCategories。

private void DeleteChildCategories(Category category) 
{
    foreach (Category subCategory in category.ChildCategories.ToList())
        {
            if (subCategory.SubCategories.Count() > 0)
            {
                DeleteChildCategories(subCategory);
            }
            else
            {
                _db.Category.Remove(subCategory);
            }
        }
    _db.Category.Remove(category);
}

您可以在删除控制器操作中的类别时调用DeleteChildCategories。

DeleteChildCategories(Category);
_db.SaveChanges();

希望这有帮助。

标记

答案 1 :(得分:0)

您似乎对类别和子类别使用相同的模型。没关系,但是当你试图激活级联删除时,你会收到无限循环,因为它不知道要删除什么。

我认为,您的模型中需要parentCategoryID属性。在这种情况下,您将拥有强大的关系并且级联删除应该有效。

<强>编辑: 我的意思是,如果你有parentCategoryID,你可以尝试按如下方式修改你的代码:

modelBuilder.Entity<Category>().HasOptional(x => x.RootCategory).WithMany(x => x.ChildCategories).HasForeignKey(x => x.parentCategoryID).WillCascadeOnDelete(true);

答案 2 :(得分:0)

我记得我遇到过类似的问题。我希望这会有所帮助:

我有一个可以回复的评论实体(其他评论),创建评论的“无限制树”。

每个Comment都有自己的CommentID(主键)以及ParentID(外键,没有CASCADE)。然后我的评论表上有一个数据库触发器:

CREATE TRIGGER [dbo].[Trigger_DeleteChildComments]
ON [dbo].[Comment]
FOR DELETE
AS
BEGIN
    SET NoCount ON
    DELETE FROM Comment WHERE ParentID IN (SELECT CommentID FROM DELETED)
END

(或者:“删除评论c后,删除所有其他以c为父母的评论。)

请注意,这仅适用,因为我的业务逻辑不允许此注释图上的“周期”,确保图形保持为树。因此,我相信我的触发器不会导致无限循环。