C# 如何设置自引用关系的级联?

C# 如何设置自引用关系的级联?,c#,asp.net-mvc,entity-framework,asp.net-mvc-4,entity-framework-5,C#,Asp.net Mvc,Entity Framework,Asp.net Mvc 4,Entity Framework 5,我有一个默认场景,您有Category本身、RootCategory和ChildCategories。如何指定fluent模型生成器在删除时级联所有子类别 模型 公共类类别 { 公共int Id{get;set;} 公共字符串名称{get;set;} 公共虚拟类别RootCategory{get;set;} 公共虚拟ICollection子类别{get;set;} 公共虚拟ICollection项{get;set;} } 我试过的 我曾尝试使用fluent model builder,但这一次

我有一个默认场景,您有
Category
本身、
RootCategory
ChildCategories
。如何指定fluent模型生成器在删除时级联所有子类别

模型
公共类类别
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟类别RootCategory{get;set;}
公共虚拟ICollection子类别{get;set;}
公共虚拟ICollection项{get;set;}
}
我试过的 我曾尝试使用fluent model builder,但这一次在我尝试更新数据库时出错

引入外键约束 表上的“FK_dbo.Categories_dbo.Categories_RootCategory_Id” “类别”可能导致循环或多个级联路径。指明 删除无操作或更新无操作,或修改其他外键 限制

模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().HasOptional(x=>x.RootCategory)。WithMany(x=>x.ChildCategories)。WillCascadeOnDelete(true);
}

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

我认为,您的模型中需要
parentCategoryID
属性。在这种情况下,你将有强大的关系,应该工作

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

modelBuilder.Entity<Category>().HasOptional(x => x.RootCategory).WithMany(x => x.ChildCategories).HasForeignKey(x => x.parentCategoryID).WillCascadeOnDelete(true);
modelBuilder.Entity().HasOptional(x=>x.RootCategory)。带有多个(x=>x.ChildCategories)。HasForeignKey(x=>x.parentCategoryID)。WillCascadeOnDelete(true);

我记得我也遇到过类似的问题。我希望这有助于:

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

每个注释都有自己的CommentID(主键)和ParentID(外键,无级联)。然后我的注释表上有一个DB触发器:

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为父项的其他注释。)


注意,这只是因为我的业务逻辑不允许“循环”“在此注释图上,确保该图保持为树。因此,我相信我的触发器不会导致无止境的循环。

我也有同样的问题。关于fluent API配置,我不知道您是否可以在那里进行。您可以做的是将WillCascadeOnDelete设置为false,然后自己删除子类别

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();
希望这有帮助


马克

暴露家长Id将如何解决问题?EF使用的数据库中已经有父\u Id。我遇到了与OP类似的问题,这可能是我最终使用的解决方案。根据您的说明,您不能对自引用表使用级联删除,无论是EF还是纯t-SQL。我也遇到了同样的问题,并且最终导致代码中的递归删除效率低下。
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(Category);
_db.SaveChanges();