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

Posted

技术标签:

【中文标题】使用 C# 将数据表转换为分层数据结构 (JSON)【英文标题】:Converting datatable into hierarchical data structure (JSON) using C# 【发布时间】:2016-06-04 18:14:19 【问题描述】:

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

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

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

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

【问题讨论】:

你能再澄清一点吗?您需要从 SQL 中获取数据并将其放入 JSON 中吗?还是您正在阅读 JSON 并希望将其存储在 C# 对象(数据结构)中?您描述的数据看起来像Tree data structure。快速搜索默认显示these aren't available in C#,但它们是一个简单的构建结构。另请查看Deserialize JSON into C# dynamic object。 @Ian。我需要从 SQL 服务器读取数据,并且我想将此数据传递给使用 angularJS 开发的前端应用程序。所以我需要将数据转换成树结构。我不能只是将数据转换为 JSON,首先我需要将数据转换为所需的格式。 所以你想去SQL -> C# data structure -> JSON?如果您使用的是实体框架,它应该从 SQL 为您生成一个模型。 我没有使用实体框架:( 那你用什么来读取数据库? 【参考方案1】:

使用您在示例中显示的固定级别层次结构,您可以使用LINQ query with grouping 为您的 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; 

以上是使用 POCO 的技术的一个工作示例。

您提到“数据表”;我假设这是指.NET DataTable class?如果是这样,您可以使用 LINQ 查询DataTable。您只需使用 DataSetExtensions 将其转换为可枚举。见:LINQ query on a DataTable

然后在 LINQ 语句中,将列表替换为数据表 .AsEnumerable(),并将属性引用替换为 .Field&lt;string&gt;("")。像这样:

DataTable dt = // load data table
var tree = from l1 in dt.AsEnumerable()
           group l1 by new  key = l1.Field<string>("Key_L1"), name = l1.Field<string>("L1")  into group1
           select new
           
               // etc.
           ;

对于可变数量的列,您必须使用递归方法,如下所示:

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)
            ;

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

【讨论】:

谢谢!!!!是的,我说的是使用 .net 数据表类。我只是想知道我们是否可以让选择多个类别变得更加动态。 我想使用.net DataTable 类,所以我不必自己创建结构(data class in this case)。您能否也包括一个带有数据表的示例。 @OpenStack 你看过 LINQ-to-DataTable 文章吗?无论如何,我举一个简短的例子。

以上是关于使用 C# 将数据表转换为分层数据结构 (JSON)的主要内容,如果未能解决你的问题,请参考以下文章

如何将分层表转换为json

在 C# 中将数据表转换为 JSON

如何使用 json.net 将 c# 通用列表转换为 json?

如何使用 json.net 将 c# 通用列表转换为 json?

Swifty JSON:将 JSON 数组中的对象分层列表转换为分层 Swift 对象

怎样将json数据转换成匿名数组或者泛型对象(c#)