如何通过嵌套级别获取嵌套行?

时间:2017-10-10 08:38:01

标签: c# sql-server linq

我的下表包含属性:IdParentIdName等。 该表包含嵌套级别:Objects包含Elements,其中包含Components)。

Id | Parent | Name
---------------------------------------
1  | NULL   | Name (this is object 1)    
2  | 1      |  Name (this is element 1)
3  | 2      |   Name (this is component 1)
4  | 2      |   Name (this is component 2)
5  | 2      |   Name (this is component 3)
6  | 1      |  Name (this is element 2)
7  | 6      |   Name (this is component 4)
8  | 1      |  Name (this is element 3)
9  | NULL   | Name (this is object 2)
10 | 9      |  Name (this is element 4)
11 | 10     |   Name (this is component 5)
12 | 10     |   Name (this is component 6)

我需要一个LINQ查询来处理此结果,如同在显示的表中一样。

我不想使用nested for loops获取对象,然后为每个对象获取其元素,然后为每个元素获取其组件 - 同样用于表上的递归,我不想要这个。

1 个答案:

答案 0 :(得分:0)

不适合一个linq声明。使用递归方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;


namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Id", typeof(int));
            dt.Columns.Add("Parent", typeof(int));
            dt.Columns.Add("Name", typeof(string));

            dt.Rows.Add(new object[] { 1, null, "Name (this is object 1)" });
            dt.Rows.Add(new object[] { 2, 1, "Name (this is element 1)" });
            dt.Rows.Add(new object[] { 3, 2, "Name (this is component 1)" });
            dt.Rows.Add(new object[] { 4, 2, "Name (this is component 2)" });
            dt.Rows.Add(new object[] { 5, 2, "Name (this is component 3)" });
            dt.Rows.Add(new object[] { 6, 1, "Name (this is element 2)" });
            dt.Rows.Add(new object[] { 7, 6, "Name (this is component 4)"});
            dt.Rows.Add(new object[] { 8, 1, "Name (this is element 3)" });
            dt.Rows.Add(new object[] { 9, null, "Name (this is object 2)" });
            dt.Rows.Add(new object[] { 10, 9, "Name (this is element 4)" });
            dt.Rows.Add(new object[] { 11, 10, "Name (this is component 5)" });
            dt.Rows.Add(new object[] { 12, 10, "Name (this is component 6)" });

            Node.RecursiveFill(dt, null, Node.root);

        }

    }
    public class Node
    {
        public static Node root = new Node();

        public List<Node> children { get; set; }
        public int id { get; set; }
        public string name { get; set; }

        public static void RecursiveFill(DataTable dt, int? parentId, Node parentNode)
        {
            foreach (DataRow row in dt.AsEnumerable().Where(x => x.Field<int?>("Parent") == parentId))
            {
                Node newChild = new Node();
                if (parentNode.children == null) parentNode.children = new List<Node>();
                parentNode.children.Add(newChild);
                newChild.id = row.Field<int>("Id");
                newChild.name = row.Field<string>("Name");
                RecursiveFill(dt, newChild.id, newChild);
            }
        }
    }

}