Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用C语言将数据表的结果转换成树#_C#_Datatable_Tree_Treeview_Dataset - Fatal编程技术网

C# 用C语言将数据表的结果转换成树#

C# 用C语言将数据表的结果转换成树#,c#,datatable,tree,treeview,dataset,C#,Datatable,Tree,Treeview,Dataset,我有一个包含4列的数据集。名称、键、父键、级别。我需要将这个数据表转换成树结构。我附上一个图像,这将给你一些想法,我想做什么。将DataTable转换为可用于生成树结构的对象的最有效方法是什么。请帮忙 请注意:数据可以以任何顺序出现在DataTable中。是否可以在第一级列上对dataTable排序,然后在parentKey列上排序?我认为,如果我能做到这一点,那么将输出转换为树结构就很容易了 我添加了一个模仿dataset的类&我在datatable中对数据进行了排序 namespace S

我有一个包含4列的数据集。名称、键、父键、级别。我需要将这个数据表转换成树结构。我附上一个图像,这将给你一些想法,我想做什么。将DataTable转换为可用于生成树结构的对象的最有效方法是什么。请帮忙

请注意:数据可以以任何顺序出现在DataTable中。是否可以在第一级列上对dataTable排序,然后在parentKey列上排序?我认为,如果我能做到这一点,那么将输出转换为树结构就很容易了

我添加了一个模仿dataset的类&我在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", "A1", 2);
            table.Rows.Add("C", "A3", "A1", 2);
            table.Rows.Add("D", "A4", "A1", 2);

            table.Rows.Add("E", "A5", "A2", 3);
            table.Rows.Add("F", "A6", "A5", 4);
            table.Rows.Add("G", "A7", "A3", 3);
            table.Rows.Add("H", "A8", "A4", 3);


            table.Rows.Add("I", "A9", "A4", 3);
            table.Rows.Add("J", "A10", "A4", 3);
            table.Rows.Add("K", "A11", "A10", 4);
            table.Rows.Add("L", "A12", "A10", 4);

            table.Rows.Add("M", "A13", "A12", 5);
            table.Rows.Add("N", "A14", "A12", 5);
            table.Rows.Add("O", "A15", "A10", 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, Func<T, 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, Func<T, bool> startWith, Func<T, T, 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), connectBy, newNode));

                yield return newNode;
            }
        }
    }





}
名称空间排序数据表
{
公共课程
{
私有静态void Main(字符串[]args)
{
DataTable=新的DataTable();
表.列.添加(“名称”,类型(字符串));
表.列.添加(“键”,类型(字符串));
table.Columns.Add(“ParentKey”,typeof(string));
表.列.添加(“级别”,类型(int));
表.行.添加(“A”,“A1”,null,1);
表.行.添加(“B”、“A2”、“A1”和“2”);
表.行.添加(“C”、“A3”、“A1”和“2”);
表.行.添加(“D”、“A4”、“A1”和“2”);
表.行.添加(“E”、“A5”、“A2”和“3”);
表.行.添加(“F”、“A6”、“A5”、4);
表.行.添加(“G”、“A7”、“A3”和“3”);
表.行.添加(“H”、“A8”、“A4”和“3”);
表.行.加上(“I”、“A9”、“A4”和“3”);
表.行.添加(“J”、“A10”、“A4”和“3”);
表。行。添加(“K”、“A11”、“A10”、4);
表。行。添加(“L”、“A12”、“A10”、4);
表。行。添加(“M”、“A13”、“A12”、5);
表。行。添加(“N”、“A14”、“A12”、5);
表。行。添加(“O”、“A15”、“A10”、4);
DataView视图=table.DefaultView;
//默认情况下,第一列按升序排序。
view.Sort=“Level,ParentKey DESC”;
foreach(视图中的DataRowView行)
{
WriteLine(“{0}\t{1}\t{2}\t{3}”,行[“名称”],行[“键”],行[“父键”],行[“级别”]);
}
Console.ReadKey();
}
}
公共类节点
{
内部节点(){}
公共T项{get;内部集合;}
公共整数级别{get;内部集合;}
公共节点父节点{get;内部集;}
公共IList子项{get;内部集;}
公共静态IEnumerable ToHierarchy(IEnumerable源、Func startWith、Func connectBy)
{
如果(source==null)抛出新的ArgumentNullException(“source”);
如果(startWith==null)抛出新的ArgumentNullException(“startWith”);
如果(connectBy==null)抛出新的ArgumentNullException(“connectBy”);
返回source.ToHierarchy(startWith、connectBy、null);
}
私有静态IEnumerable ToHierarchy(IEnumerable源、Func startWith、Func connectBy、节点父节点)
{
int-level=(parent==null?0:parent.level+1);
变量根=来自源中的项
其中startWith(项目)
选择项目;
foreach(根中的T值)
{
var children=新列表();
var newNode=新节点
{
级别=级别,
父=父,
项目=价值,
Children=Children.AsReadOnly()
};
T tmpValue=值;
AddRange(source.ToHierarchy(possibleSub=>connectBy(tmpValue,possibleSub),connectBy,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,
        Func<T, bool> startWith,
        Func<T, 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>(
        this IEnumerable<T> source,
        Func<T, bool> startWith,
        Func<T, T, 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), connectBy, newNode));

            yield return newNode;
        }
    }
hierarchy
是一个
IEnumerable


请注意,如果您在
数据表
本身中定义了父子关系,那么您已经有了一个树结构。。。您只需要选择根(没有父项的项)。

什么的树结构?上课?你不需要“级别”。键和ParentKey足以在自引用表中构建无限树。@SriramSakthivel:是。“类的树结构”。@罗伯特:你能告诉我这是怎么可能的吗。您的意思是在datatable中创建关系吗?请看这篇文章,它完全涵盖了您要查找的内容:我在使用此代码时遇到编译时错误。我已经用你的回答更新了我的问题suggestion@Brown_Dynamite,ToHierarchy方法不是节点的成员,它是一个扩展方法,因此它应该位于静态类中
var hierarchy =
    sourceTable.AsEnumerable()
               .ToHierarchy(row => row.IsNull("ParentKey"),
                            (parent, child) => parent.Field<int>("Key") ==
                                               child.Field<int>("ParentKey"))