在 Entity Framework 中使用递归函数删除具有自引用外键的实体
Delete entity with self-referencing foreign key using recursive function in Entity Framework
我正在使用 Entity Framework 开发一个 ASP.NET MVC 项目 我正在使用代码优先方法。我在删除具有自引用外键的实体及其使用递归函数的相关实体时遇到问题。
我正在使用递归函数删除,因为无法在 SQL 服务器中为自引用外键设置删除级联。当我删除时,如果实体有相关实体要删除,它会抛出堆栈溢出异常。因为递归函数永远不会停止调用。它变得无限。
这是我的实体class,具有自引用 FK
public class Category
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(55)]
public string MmName { get; set; }
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public virtual Category ParentCategory { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
这就是我使用递归函数在模型中删除的方式:
public List<int> deletedIds = new List<int>();
public Category Delete(Category category)
{
if(category!=null)
{
int intentionId = category.Id;
if(category.Categories!=null && category.Categories.Count>0)
{
RelatedCategories(category.Categories);
}
deletedIds.Add(intentionId);
if(deletedIds.Count>0)
{
IEnumerable<Category> categories = context.Categories.Where(x => deletedIds.Contains(x.Id));
if(categories!=null && categories.Count()>0)
{
context.Categories.RemoveRange(categories);
context.SaveChanges();
}
}
}
return category;
}
private void RelatedCategories(IEnumerable<Category> categories)
{
foreach(var c in categories)
{
deletedIds.Add(c.Id);
while (c.Categories!=null && c.Categories.Count > 0)
{
RelatedCategories(c.Categories);
}
}
}
我正在删除这个结构中的数据
我正在删除 test1。但是当递归函数本身被调用时,它只是一直通过 test2 传递 List 。我该如何修复我的代码?如何使用递归函数删除类别及其相关类别?
我试过这个来停止递归。就是停不下来,还是一样。
private void RelatedCategories(IEnumerable<Category> categories)
{
Category repeatedCategory = null;
if(categories!=null && categories.Count()>0 && deletedIds.Count>0)
{
repeatedCategory = categories.FirstOrDefault(x => deletedIds.Contains(categories.Select(c => c.Id).FirstOrDefault()));
}
if(repeatedCategory!=null)
{
return;
}
foreach(var c in categories)
{
deletedIds.Add(c.Id);
while (c.Categories!=null && c.Categories.Count > 0)
{
RelatedCategories(c.Categories);
}
}
}
我发现了错误。递归是我的错。我在递归函数中使用了 while 循环。所以它变成了无限循环。实际上我需要改用 if 语句。我只是用这个功能替换了。效果很好。
private void RelatedCategories(IEnumerable<Category> categories)
{
foreach (var c in categories)
{
deletedIds.Add(c.Id);
if(c.Categories!=null && c.Categories.Any())
{
SetRelatedCategories(c.Categories);
}
}
}
我正在使用 Entity Framework 开发一个 ASP.NET MVC 项目 我正在使用代码优先方法。我在删除具有自引用外键的实体及其使用递归函数的相关实体时遇到问题。
我正在使用递归函数删除,因为无法在 SQL 服务器中为自引用外键设置删除级联。当我删除时,如果实体有相关实体要删除,它会抛出堆栈溢出异常。因为递归函数永远不会停止调用。它变得无限。
这是我的实体class,具有自引用 FK
public class Category
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(55)]
public string MmName { get; set; }
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public virtual Category ParentCategory { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
这就是我使用递归函数在模型中删除的方式:
public List<int> deletedIds = new List<int>();
public Category Delete(Category category)
{
if(category!=null)
{
int intentionId = category.Id;
if(category.Categories!=null && category.Categories.Count>0)
{
RelatedCategories(category.Categories);
}
deletedIds.Add(intentionId);
if(deletedIds.Count>0)
{
IEnumerable<Category> categories = context.Categories.Where(x => deletedIds.Contains(x.Id));
if(categories!=null && categories.Count()>0)
{
context.Categories.RemoveRange(categories);
context.SaveChanges();
}
}
}
return category;
}
private void RelatedCategories(IEnumerable<Category> categories)
{
foreach(var c in categories)
{
deletedIds.Add(c.Id);
while (c.Categories!=null && c.Categories.Count > 0)
{
RelatedCategories(c.Categories);
}
}
}
我正在删除这个结构中的数据
我正在删除 test1。但是当递归函数本身被调用时,它只是一直通过 test2 传递 List 。我该如何修复我的代码?如何使用递归函数删除类别及其相关类别?
我试过这个来停止递归。就是停不下来,还是一样。
private void RelatedCategories(IEnumerable<Category> categories)
{
Category repeatedCategory = null;
if(categories!=null && categories.Count()>0 && deletedIds.Count>0)
{
repeatedCategory = categories.FirstOrDefault(x => deletedIds.Contains(categories.Select(c => c.Id).FirstOrDefault()));
}
if(repeatedCategory!=null)
{
return;
}
foreach(var c in categories)
{
deletedIds.Add(c.Id);
while (c.Categories!=null && c.Categories.Count > 0)
{
RelatedCategories(c.Categories);
}
}
}
我发现了错误。递归是我的错。我在递归函数中使用了 while 循环。所以它变成了无限循环。实际上我需要改用 if 语句。我只是用这个功能替换了。效果很好。
private void RelatedCategories(IEnumerable<Category> categories)
{
foreach (var c in categories)
{
deletedIds.Add(c.Id);
if(c.Categories!=null && c.Categories.Any())
{
SetRelatedCategories(c.Categories);
}
}
}