[英]StackOverFlowException inside a recursive function
I have a table in database as follows: 我在数据库中有一个表,如下所示:
MenuItem
-------------
MenuItemId 1 --------+
MenuItemName |
ParentId * --------+
Now I have written a recursive function to get all the Parent MenuItems with their children. 现在,我编写了一个递归函数来获取所有Parent MenuItems及其子级。
private ICollection<MenuItem> GetAllChildrenOfSpecificMenuItemRecursively(MenuItem menuItem, IEnumerable<MenuItem> menuItems)
{
ICollection<MenuItem> Children = null;
foreach (MenuItem mi in menuItems)
{
if (mi.ParentMenuItemId != null)
{
if (mi.ParentMenuItemId == menuItem.MenuItemId)
{
Children.Add(mi);
}
else
{
return GetAllChildrenOfSpecificMenuItemRecursively(mi, menuItems);
}
}
}
return Children;
}
Now, I am calling it from another function as follows: 现在,我从另一个函数中调用它,如下所示:
public IEnumerable<MenuItem> GetAllParentMenuItemsWithChildren()
{
List<MenuItem> MenuItems = new List<MenuItem>();
IEnumerable<MenuItem> AllMenuItems = null;
using (MaxContext entityContext = new MaxContext())
{
AllMenuItems = (from e in entityContext.MenuItemSet select e).ToList();
foreach (MenuItem menuItem in entityContext.MenuItemSet)
{
if (menuItem.ParentMenuItemId == null)
{
menuItem.Children = GetAllChildrenOfSpecificMenuItemRecursively(menuItem, AllMenuItems);
MenuItems.Add(menuItem);
}
}
}
return MenuItems;
}
But it gives me stackoverflowException inside the recursive function. 但这给了我递归函数内部的stackoverflowException。 I am sure that I am making a minor mistake in that function.
我确信我在该功能中犯了一个小错误。 Can anybody point out that mistake?
有人可以指出那个错误吗?
Your GetAllChildrenOfSpecificMenuItemRecursively()
always recurses with mi
. 您的
GetAllChildrenOfSpecificMenuItemRecursively()
总是与mi
递归。 It should recurse with mi.ParentMenuItemId
instead. 它应改为使用
mi.ParentMenuItemId
递归。
Why are you always passing the same menuItems
colleciton into recursive function? 为什么总是将相同的
menuItems
colleciton传递给递归函数?
your code should be something along the lines of: 您的代码应类似于以下内容:
private IEnumerable<MenuItem> GetAllChildrenOfSpecificMenuItemRecursively(MenuItem menuItem)
{
var children = new List<MenuItem>();
foreach (MenuItem mi in menuItem.Children)
{
// Why are you checking this?
if (mi.ParentMenuItemId != null)
{
// Why are you checking this?
if (mi.ParentMenuItemId == menuItem.MenuItemId)
{
children.Add(mi);
}
else
{
children.AddRange(GetAllChildrenOfSpecificMenuItemRecursively(mi))
}
}
}
return Children;
}
From method name, this is all that it should be doing: 从方法名称来看,这就是它应该做的所有事情:
private IEnumerable<MenuItem> GetAllChildrenOfSpecificMenuItemRecursively(MenuItem menuItem)
{
var children = new List<MenuItem>();
if (menuItem.Children == null) return children;
foreach (MenuItem mi in menuItem.Children)
{
children.Add(mi);
children.AddRange(GetAllChildrenOfSpecificMenuItemRecursively(mi));
}
return Children;
}
Edit: 编辑:
public class MenuItem
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
public virtual MenuItem Parent { get; set; }
[InverseProperty("Parent")]
public virtual ICollection<MenuItem> Children { get; set; }
}
I think there is a simpler (and maybe faster) way of doing this without using recursion. 我认为有一种更简单(甚至更快)的方法,无需使用递归。 Something like this:
像这样:
public ICollection<MenuItem> GetMenuItemsAsTreeList()
{
AllMenuItems = entityContext.MenuItemSet.ToList();
Dictionary<int, MenuItem> dic = AllMenuItems.ToDictionary(n => n.Id, n => n);
List<MenuItem> rootMenuItems = new List<MenuItem>();
foreach (MenuItem menuItem in AllMenuItems)
{
if (menuItem.ParentMenuItemId.HasValue)
{
MenuItem parent = dic[menuItem.ParentMenuItemId.Value];
menuItem.ParentMenuItem = parent;
parent.SubMenuItems.Add(menuItem);
}
else
{
rootMenuItems.Add(menuItem);
}
}
return rootMenuItems;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.