递归Hierarchical Parent子级

时间:2013-08-03 06:35:00

标签: c# .net algorithm linq

我有一个来自数据库的项目集合,其值为parentid或为空。

这是我的班级设计:

public class Item
{
public int id{get;set;}
public string Name{get;set;}
public int? ParentId{get;set;}
public List<Item> SubItems{get;set;}
}

我想从集合中构建Items的层次结构。假设一个集合是100个项目,我需要根据ParentId映射构建结构。

我试过这篇文章Recursive Hierarchical Joins in C# and LINQ  但如果ParentId为null,它会给我一个错误。

还尝试了Build tree type list by recursively checking parent-child relationship C#,但此解决方案对我来说也不起作用。

我如何实现这一目标?

3 个答案:

答案 0 :(得分:7)

你可以使用这种方法:

  1. 从数据库中获取所有项目(不填写SubItems)。
  2. 使用该父ID构建Lookup<int?,Item>个父ID和项目。
  3. 循环浏览项目并使用查找将每个项目与子项目相关联。
  4. 代码:

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

答案 1 :(得分:0)

你真的需要一个子项目的setter吗?在SQL服务器上运行选择* 查询时,请注意性能问题。

  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是保留字。 )

答案 2 :(得分:0)

使用此Node class,您只需执行此操作:

var flatListOfItems = GetItemsFromDatabase();
var rootNodes =Node<Item>.CreateTree(flatListOfItems, i => i.id, i => i.ParentId);

您的项目不再需要子项,因为Node类具有子项和后代属性。 (还有祖先,兄弟姐妹,等级等)。

CreateTree方法会生成一个或多个根节点。如果你确定总有1个rootnode,你可以使用rootNodes.Single()来获取root。