C#将扁平化数据以 JSON 树形结构输出
# 前言
在做宿舍房间选择器的时候,需要用到 楼栋-楼层-房间号 对应关系的数据,开发中后台我使用的是 C# 语言,使用 SQL 查询出来的数据会使用 DataTable 对象储存,其中包含了一些关于公司、楼栋和房间的信息。这是一个扁平的数据结构,不具备层次关系。我们的目标是将这些数据转化为JSON格式,以便在前端使用。
# 问题
最开始我是直接在前端使用 JS 一把梭的,用了一段时间后发现因为要处理的数据量庞大,导致前端页面响应缓慢,性能受限,于是便开始寻求更好的优化方案。
# LINQ 查询
经过一番查找发现可以在后台编写 C# 代码时可以用 LINQ (opens new window) 查询来处理这些扁平化数据:
笔记
指定在返回这些信息之前如何对其进行排序、分组和结构化。 查询存储在查询变量中,并用查询表达式进行初始化。
它可以很方便的将数据按指定格式输出。
# 使用 LINQ
假如我们有以下数据:
COMPANYCODE | BUILDNO | ID
------------|---------|---
A | B1 | 1
A | B2 | 2
B | C1 | 3
B | C2 | 4
2
3
4
5
6
使用LINQ语句对数据进行分组,根据公司代码(COMPANYCODE)进行分组。这一步将数据按照公司代码分成若干组,形成一个分层结构的基础。
var treeData = from row in dataTable.AsEnumerable()
group row by row.Field<string>("COMPANYCODE") into buildingGroup
select new
{
value = buildingGroup.Key,
text = buildingGroup.Key,
children = from roomRow in buildingGroup
select new
{
text = roomRow.Field<string>("BUILDNO"),
value = roomRow.Field<string>("ID")
}
};
2
3
4
5
6
7
8
9
10
11
12
13
这里我们使用 group by
将数据按照公司代码分组,然后构建了一个匿名类型的集合。其中,value
和 text
是用于表示公司代码的属性,children
则是一个子集合,表示楼栋的信息,可以以此类推遍历出楼层,房间号的对应关系,这里就不写了。
这时我们就得到了我们想要的分层结构数据,接下来就要输出数据发送给前端了,这里使用 JavaScriptSerializer
类序列化数据。
# JavaScriptSerializer
使用 JavaScriptSerializer
类将 LINQ 查询的结果序列化为 JSON 字符串:
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(treeData);
2
JavaScriptSerializer
是一个在 C# 中用于序列化和反序列化 JSON 数据的类。通过调用 Serialize
方法,我们将 LINQ 查询的结果转化为符合 JSON 格式的字符串。
警告
如果 .NET Framework 版本低于4.7.2,要引用 Newtonsoft.Json 。 说明 (opens new window)
# 结果
经过上面一系列操作,我们就能得到这样的 JSON 数据结构:
[
{
"value": "A",
"text": "A",
"children": [
{ "text": "B1", "value": "1" },
{ "text": "B2", "value": "2" }
]
},
{
"value": "B",
"text": "B",
"children": [
{ "text": "C1", "value": "3" },
{ "text": "C2", "value": "4" }
]
}
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 结语
使用 LINQ 和 JavaScriptSerializer
将扁平化的数据组织成树形结构的JSON数据。这种方法不仅简洁高效,而且提供了清晰易懂的代码结构,可以方便前端开发。