将数据表转换为嵌套的LIST<> [英] Convert datatable to nested LIST <>
本文介绍了将数据表转换为嵌套的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 achart
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 anint
, not astring
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<>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文