将数据表转换为嵌套的LIST<> [英] Convert datatable to nested LIST <>

查看:96
本文介绍了将数据表转换为嵌套的LIST<>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据表如下



I have a data table as following

ID    Name   ParentID
1      A       0
2      B       1
3      C       1
4      D       2
5      E       3
6      F       4





我想要这个列表<图表>





I want this as a List<chart>

//Chart.cs
 public int ID { get; set; }
 public string Name { get; set; }
 public string ParentID{ get; set; }
 public List<chart> lstChild{ get; set; }





我尝试过:



我试过这个功能:





What I have tried:

I have tried this function:

public static void MakeTree(DataTable dt, clsChart parent)
        {
            foreach (DataRow row in dt.AsEnumerable().Where(x => x.Field<int>("ParentID") == parent.ID))
            {
                if (parent.lstChildren == null)
                {
                    parent.lstChildren = new List<clschart>();
                }
                clsChart newNode = new clsChart();
                newNode.Name = row.Field<string>("Name");
                newNode.ID = row.Field<int>("EntryID");
                parent.lstChildren.Add(newNode);
                MakeTree(dt, newNode);
            }
        }





但它不会返回 List<> ;, 它返回类

推荐答案

对于我来说,你的数据表是为分层数据模型 [ ^ ]。这就是图表模型应该反映到数据表模型的原因。

As to me, your datatable is designed properly for hierarchical data model[^]. That's why a chart model should reflect to a datatable model.
public class chart
{
	public int ID { get; set; }
 	public string Name { get; set; }
	public int ParentID{ get; set; }
}





这很容易创建列表< chart> 来自您的数据表:



This is very easy to create a List<chart> from your datatable:

List<chart> charts = dt.AsEnumerable()
    .Select(dr=> new chart()
        {
            ID=dr.Field<int>("ID"),
            Name=dr.Field<string>("Name"),
            ParentID=dr.Field<int>("ParentID")
        })
    .ToList();





以上型号是分层数据的平面版本。如果您想创建更高级的层次结构,请阅读:
递归层次结构加入C#和LINQ - Bitlush [ ^ ]


您可以递归创建(和链接)节点,但是还需要在创建每个节点时添加的主列表节点。



主列表代表完全展开的树;如果节点有子节点,则节点可扩展/可折叠。



预制树视图维护内部树视图列表(同样的事情)。



每个项目的级别决定了缩进。



在创建树时添加级别编号非常有用。使用级别编号,您还可以在使用复合键时推断父级(如果有)。
You can recursively create (and link) your nodes, but you also need a "master list" that you add to when you create each node.

The "master list" represents the fully expanded tree; a node is expandable / collapsible if it has children.

"Canned" tree views maintain an internal "tree view list" (same thing).

The "level" of each item determines the indenting.

Adding a "level number" is useful when creating tree. With a level number, you can also infer the parent, if any, when using compound keys.


首先,ParentID应该是 int ,而不是字符串



其次,根本不需要递归,并提供父节点总是在孩子面前定义,你可以使用一个循环。 (如果是随机顺序,则首先创建一个节点集合,然后循环遍历:

Firstly, ParentID should be an int, not a string

Secondly, you don't need recursion at all, and provided your parent nodes are always defined before their children, you can use a single loop. (If it's a random order, then create a node collection first, and then loop through that afterwards:
class Chart
    {
    private static Dictionary<int, Chart> all = new Dictionary<int, Chart>();
    public int ID { get; set; }
    public string Name { get; set; }
    public int ParentID { get; set; }
    public List<Chart> Children { get; set; } = new List<Chart>();
    private Chart(DataRow row)
        {
        ID = (int)row["ID"];
        Name = (string)row["Name"];
        ParentID = (int)row["ParentID"];
        all[ID] = this;
        }
    public static Chart MakeTree(DataTable dt)
        {
        List<Chart> nodes = new List<Chart>();
        Chart root = null;
        foreach (DataRow row in dt.AsEnumerable())
            {
            Chart node = new Chart(row);
            if (node.ParentID == 0)
                {
                if (root != null) throw new ArgumentException("Too many ROOT nodes: only one was expected.");
                root = node;
                }
            else
                {
                if (root == null) throw new ArgumentException("ROOT node has not been defined: one is required.");
                Chart parent = all[node.ParentID];
                parent.Children.Add(node);
                }
            }
        return root;
        }
    }




DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("ParentID", typeof(int));
dt.Rows.Add(1, "A", 0);
dt.Rows.Add(2, "B", 1);
dt.Rows.Add(3, "C", 1);
dt.Rows.Add(4, "D", 2);
dt.Rows.Add(5, "E", 3);
dt.Rows.Add(6, "F", 4);
Chart root = Chart.MakeTree(dt);


这篇关于将数据表转换为嵌套的LIST&lt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆