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();