递归层次父子关系
本文关键字:父子关系 层次 递归 | 更新日期: 2023-09-27 18:25:58
我有一个来自parentid
值或null的数据库的项集合。
这是我的课堂设计:
public class Item
{
public int id{get;set;}
public string Name{get;set;}
public int? ParentId{get;set;}
public List<Item> SubItems{get;set;}
}
我想从集合中构建一个项目的层次结构。假设一个集合是100个项目,我需要从中构建基于ParentId映射的结构。
我在C#和LINQ中尝试过这个帖子递归层次连接但如果ParentId为null,则会给我一个错误。
还尝试过通过递归检查父子关系C#来构建树类型列表,但这个解决方案也不适用于我
我该如何做到这一点?
您可以使用这种方法:
- 从数据库中获取所有项目(不填充SubItems)
- 构建父id和具有该父id的项的
Lookup<int?,Item>
- 循环浏览这些项,并使用查找将每个项与子项相关联
代码:
var items = // get from the database... (e.g. as a list)
var lookup = items.ToLookup(x => x.ParentId);
foreach (var item in items)
item.SubItems = lookup[item.Id].ToList();
正如@EamonNerbonne在下面评论的那样,如果需要,您也可以获得根元素:
var roots = lookup[null].ToList();
使用此Node类,您可以简单地执行以下操作:
var flatListOfItems = GetItemsFromDatabase();
var rootNodes =Node<Item>.CreateTree(flatListOfItems, i => i.id, i => i.ParentId);
您的项不再需要子项,因为Node类具有子项和子项属性。(还有祖先、兄弟姐妹、等级等)。
CreateTree方法会产生一个或多个根节点。如果你确定总是有一个根节点,你可以执行rootNodes.Single()来获取根。
您真的需要一个子项的setter吗?在SQL server上运行Select*查询时,还要注意性能问题。
public List<Item> SubItems{
get
{
try{
var validParents = db.items.Where(x=>x.ParentId!=null && x.ParentId.Equals(Id)); //db is your dbcontext
if(validParents !=null)
{
return validParents.ToList();
}else
{
return null;
}
catch(Exception)
{
return null;
}
}
(注意:考虑将其添加到分部实体类中。永远不要将实体命名为"Item":)。Item是一个保留字。)