在 C# 中按层次结构显示父子元素



我的数据库中有一个父子结构,我想在 C# 程序中分层列出它们:

id  text  parentid
1   A     NULL
2   B     NULL
5   a1    1
6   b1    2
9   a11   5
10  a12   5
11  b12   6

类:

 public class Category
    {
        public int id { get; set; }       
        public string text{ get; set; }     
        public int? ParentId { get; set; }        
        public List<Category> children;
    }

这是我创建嵌套列表的尝试:

List<Category> cats = new List<Category>();
while (sdr.Read())
{
     Category c = new Category();
     //filling class list from db
     cats.Add(c);
}
var child=cats.ToLookup(cat=>cat.ParentId );
foreach (var cat in cats)
     cat.children=child[cat.id].ToList();

上述代码的 JSON 输出:

[{"children":[{"children":[{"children":[],"id":9,"text":"a11","ParentId":5},{"children":[],"id":10,"text":"a12","ParentId":5}],"id":5,"text":"a1","ParentId":1}],"id":1,"text":"A","ParentId":null},{"children":[{"children":[{"children":[],"id":11,"text":"b12","ParentId":6}],"id":6,"text":"b1","ParentId":2}],"id":2,"text":"B","ParentId":null},{"children":[{"children":[],"id":9,"text":"a11","ParentId":5},{"children":[],"id":10,"text":"a12","ParentId":5}],"id":5,"text":"a1","ParentId":1},{"children":[{"children":[],"id":11,"text":"b12","ParentId":6}],"id":6,"text":"b1","ParentId":2},{"children":[],"id":9,"text":"a11","ParentId":5},{"children":[],"id":10,"text":"a12","ParentId":5},{"children":[],"id":11,"text":"b12","ParentId":6}]

问题是上面的代码表示同一级别的所有 id。它重复子元素,将它们置于同一级别(根项)。

这是预期的输出:

[{
        "children": [{
            "children": [{
                "children": [],
                "id": 9,
                "text": "a11",
                "ParentId": 5
            }, {
                "children": [],
                "id": 10,
                "text": "a12",
                "ParentId": 5
            }],
            "id": 5,
            "text": "a1",
            "ParentId": 1
        }],
        "id": 1,
        "text": "A",
        "ParentId": null
    }, {
        "children": [{
            "children": [{
                "children": [],
                "id": 11,
                "text": "b12",
                "ParentId": 6
            }],
            "id": 6,
            "text": "b1",
            "ParentId": 2
        }],
        "id": 2,
        "text": "B",
        "ParentId": null
    }]

如何通过代码实现这种结构?

您可以使用递归方法,从没有父 id 的项目开始:

var categories = new List<Category>();
GetCategories(ref categories);
void GetCategories(ref List<Category> categories, int? parentId = null)
{
    string query = string.Empty; 
    if (parentId.HasValue)
    {
        query = "SELECT * FROM categories WHERE parentid=@parentid";         
    }
    else
    {
        query = "SELECT * FROM categories WHERE parentid IS NULL";
    }
    using (var conn = new SqlConnection(connStr))
    {
        using (var command = new SqlCommand(query, conn))
        {
            conn.Open();
            if (parentId.HasValue)
            {
                command.Parameters.AddWithValue("@parentid", parentId.Value);
            }
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                   var c = new Category();
                   c.text = reader["text"];
                   //etc..
                   categories.Add(c);
                   c.children = new List<Category>();
                   GetCategories(ref c.children, c.id);
                }
            }
        }
   }
}

试试这个

    var allCategories = new List<Category>();

获取数据后...

    var children = allCategories.ToLookup(cat => cat.ParentId);
    foreach (var category in allCategories)
    {
        category.Children = children[category.ParentId].ToList();
    }

平面列表到层次结构

public class TreeObject
  {
     public int ID { get; set; }
     public int ParentID { get; set; }
     public string Name { get; set; }
     public List<TreeObject> Children { get; set; } = new List<TreeObject>();
  }

将平面列表发送到此方法并获取层次结构(父/子)对象列表

public List<TreeObject> FlatToHierarchy(List<TreeObject> list)
        {
           
            var lookup = new Dictionary<int, TreeObject>();
            var nested = new List<TreeObject>();
            foreach (TreeObject item in list)
            {
                if (lookup.ContainsKey(item.ParentID))
                {
                    // add to the parent's child list 
                    lookup[item.ParentID].Children.Add(item);
                }
                else
                {
                    // no parent added yet (or this is the first time)
                    nested.Add(item);
                }
                lookup.Add(item.ID, item);
            }
            return nested;
        }

最新更新