C# 使用C将datatable转换为分层数据结构(JSON)

C# 使用C将datatable转换为分层数据结构(JSON),c#,.net,json,linq,c#-4.0,C#,.net,Json,Linq,C# 4.0,我正在对datatable执行SQL查询。查询可以返回多个列。结果是键值格式,表示分层数据。请参见下面的屏幕截图 图中显示了3个部分。首先是数据,然后是数据和JSON等价物的分层表示 目前,图像显示了4个级别的数据,但我们可以有6-7个级别的数据。格式将保持不变,但列数可以更改 如何使用C获得所需的结果?我知道这是一个基本的编程,但我很难用它 对于示例中所示的固定级别层次结构,您可以使用生成JSON的树结构。以下是一个具有三级层次结构的示例: static void Main(string[]

我正在对datatable执行SQL查询。查询可以返回多个列。结果是键值格式,表示分层数据。请参见下面的屏幕截图

图中显示了3个部分。首先是数据,然后是数据和JSON等价物的分层表示

目前,图像显示了4个级别的数据,但我们可以有6-7个级别的数据。格式将保持不变,但列数可以更改


如何使用C获得所需的结果?我知道这是一个基本的编程,但我很难用它

对于示例中所示的固定级别层次结构,您可以使用生成JSON的树结构。以下是一个具有三级层次结构的示例:

static void Main(string[] args)
{
    var data = new List<Data>
    {
        new Data("Food", "1_g", "beverage", "2_b", "hot", "3_h"),
        new Data("Food", "1_g", "beverage", "2_b", "cold", "3_c"),
        new Data("Food", "1_g", "fruit", "2_f", "juicy", "3_j"),
        new Data("Food", "1_g", "fruit", "2_f", "solid", "3_s"),
        new Data("Food", "1_g", "cookie", "2_c", "chocolate", "3_cho"),
    };

    var tree = from l1 in data
                group l1 by new { key = l1.Key_L1, name = l1.L1 } into group1
                select new
                {
                    key = group1.Key.key,
                    name = group1.Key.name,
                    children = from l2 in group1
                                group l2 by new { key = l2.Key_L2, name = l2.L2 } into group2
                                select new
                                {
                                    key = group2.Key.key,
                                    name = group2.Key.name,
                                    children = from l3 in group2
                                                select new { key = l3.Key_L3, name = l3.L3 }
                                }
                };

    var serializer = new JavaScriptSerializer();
    Console.WriteLine(serializer.Serialize(tree));
    Console.ReadLine();
}

class Data
{
    public Data(string l1, string k1, string l2, string k2, string l3, string k3)
    {
        L1 = l1; Key_L1 = k1;
        L2 = l2; Key_L2 = k2;
        L3 = l3; Key_L3 = k3;
    }
    public string L1 { get; set; }
    public string Key_L1 { get; set; }
    public string L2 { get; set; }
    public string Key_L2 { get; set; }
    public string L3 { get; set; }
    public string Key_L3 { get; set; }
}
对于数量可变的列,必须使用递归方法,如下所示:

var tree = Descend(dt.AsEnumerable(), 1, 3);

private static System.Collections.IEnumerable Descend(IEnumerable<DataRow> data, int currentLevel, int maxLevel)
{
    if (currentLevel > maxLevel)
    {
        return Enumerable.Empty<object>();
    }
    return from item in data
            group item by new
            {
                key = item.Field<string>("Key_L" + currentLevel),
                name = item.Field<string>("L" + currentLevel)
            } into rowGroup
            select new
            {
                key = rowGroup.Key.key,
                name = rowGroup.Key.name,
                children = Descend(rowGroup, currentLevel + 1, maxLevel)
            };
}

需要注意的一点是,这种方法在叶节点上创建了一个空的子集合。

您能进一步澄清一下吗?您需要从SQL获取数据并将其放入JSON吗?或者您正在读取JSON并希望将其存储在C对象数据结构中?您所描述的数据看起来像一个。默认情况下指示快速搜索,但它们是一个简单的构建结构。再看看伊恩。我需要从SQLServer读取数据&我想将这些数据传递给使用angularJS开发的前端应用程序。所以我需要将数据转换成树形结构。我不能只是将数据转换成JSON,首先我需要将数据转换成所需的格式。所以你想使用SQL->C数据结构->JSON?如果您使用实体框架,它应该从SQL中为您生成一个模型。我没有使用实体框架:那么您使用什么从数据库中读取?谢谢!!!!是的,我说的是使用.NETDataTable类。我只是想知道我们是否可以使选择多个类别更具动态性。我想使用.net DataTable类,所以在这种情况下我不必自己创建结构数据类。你能不能也包括一个datatable的例子。@OpenStack你看过LINQ to datatable的文章了吗?总之,我举了一个简单的例子。
var tree = Descend(dt.AsEnumerable(), 1, 3);

private static System.Collections.IEnumerable Descend(IEnumerable<DataRow> data, int currentLevel, int maxLevel)
{
    if (currentLevel > maxLevel)
    {
        return Enumerable.Empty<object>();
    }
    return from item in data
            group item by new
            {
                key = item.Field<string>("Key_L" + currentLevel),
                name = item.Field<string>("L" + currentLevel)
            } into rowGroup
            select new
            {
                key = rowGroup.Key.key,
                name = rowGroup.Key.name,
                children = Descend(rowGroup, currentLevel + 1, maxLevel)
            };
}