使用C#将数据表的结果转换为树
发布时间:2020-12-15 05:41:05 所属栏目:百科 来源:网络整理
导读:我有一个包含4列的数据集.名称,密钥,parentKey,级别.我需要将此DataTable转换为树结构.我附上一张图片,可以让你知道我想做什么.将DataTable转换为可用于生成树结构的对象的最有效方法是什么.请帮忙. 请注意:数据可以在DataTable中以任何顺序出现.是否可以在
我有一个包含4列的数据集.名称,密钥,parentKey,级别.我需要将此DataTable转换为树结构.我附上一张图片,可以让你知道我想做什么.将DataTable转换为可用于生成树结构的对象的最有效方法是什么.请帮忙.
请注意:数据可以在DataTable中以任何顺序出现.是否可以在第一级列上然后在parentKey列上对dataTable进行排序?我想,如果我能做到这一点,将输出转换为树结构会很容易. 我添加了一个模仿数据集的类.我已经在数据表中对数据进行了排序. namespace SortDataTable { public class Program { private static void Main(string[] args) { DataTable table = new DataTable(); table.Columns.Add("Name",typeof (string)); table.Columns.Add("Key",typeof (string)); table.Columns.Add("ParentKey",typeof (string)); table.Columns.Add("Level",typeof (int)); table.Rows.Add("A","A1",null,1); table.Rows.Add("B","A2",2); table.Rows.Add("C","A3",2); table.Rows.Add("D","A4",2); table.Rows.Add("E","A5",3); table.Rows.Add("F","A6",4); table.Rows.Add("G","A7",3); table.Rows.Add("H","A8",3); table.Rows.Add("I","A9",3); table.Rows.Add("J","A10",3); table.Rows.Add("K","A11",4); table.Rows.Add("L","A12",4); table.Rows.Add("M","A13",5); table.Rows.Add("N","A14",5); table.Rows.Add("O","A15",4); DataView view = table.DefaultView; // By default,the first column sorted ascending. view.Sort = "Level,ParentKey DESC"; foreach (DataRowView row in view) { Console.WriteLine(" {0} t {1} t {2} t {3}",row["Name"],row["Key"],row["ParentKey"],row["Level"]); } Console.ReadKey(); } } public class Node<T> { internal Node() { } public T Item { get; internal set; } public int Level { get; internal set; } public Node<T> Parent { get; internal set; } public IList<Node<T>> Children { get; internal set; } public static IEnumerable<Node<T>> ToHierarchy<T>( IEnumerable<T> source,Func<T,bool> startWith,T,bool> connectBy) { if (source == null) throw new ArgumentNullException("source"); if (startWith == null) throw new ArgumentNullException("startWith"); if (connectBy == null) throw new ArgumentNullException("connectBy"); return source.ToHierarchy(startWith,connectBy,null); } private static IEnumerable<Node<T>> ToHierarchy<T>(IEnumerable<T> source,bool> connectBy,Node<T> parent) { int level = (parent == null ? 0 : parent.Level + 1); var roots = from item in source where startWith(item) select item; foreach (T value in roots) { var children = new List<Node<T>>(); var newNode = new Node<T> { Level = level,Parent = parent,Item = value,Children = children.AsReadOnly() }; T tmpValue = value; children.AddRange(source.ToHierarchy(possibleSub => connectBy(tmpValue,possibleSub),newNode)); yield return newNode; } } } } 解决方法
我使用以下扩展方法来做这种事情:
public class Node<T> { internal Node() { } public T Item { get; internal set; } public int Level { get; internal set; } public Node<T> Parent { get; internal set; } public IList<Node<T>> Children { get; internal set; } } public static IEnumerable<Node<T>> ToHierarchy<T>( this IEnumerable<T> source,bool> connectBy) { if (source == null) throw new ArgumentNullException("source"); if (startWith == null) throw new ArgumentNullException("startWith"); if (connectBy == null) throw new ArgumentNullException("connectBy"); return source.ToHierarchy(startWith,null); } private static IEnumerable<Node<T>> ToHierarchy<T>( this IEnumerable<T> source,Node<T> parent) { int level = (parent == null ? 0 : parent.Level + 1); var roots = from item in source where startWith(item) select item; foreach (T value in roots) { var children = new List<Node<T>>(); var newNode = new Node<T> { Level = level,Children = children.AsReadOnly() }; T tmpValue = value; children.AddRange(source.ToHierarchy(possibleSub => connectBy(tmpValue,newNode)); yield return newNode; } } 在DataTable作为源的情况下,您可以像这样使用它: var hierarchy = sourceTable.AsEnumerable() .ToHierarchy(row => row.IsNull("ParentKey"),(parent,child) => parent.Field<int>("Key") == child.Field<int>("ParentKey")) (层次结构是IEnumerable< Node< DataRow>>) 请注意,如果在DataTable本身中定义父子关系,则您已经有了树结构……您只需选择根(没有父项的项). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |