如何将DataTable转换为带头部信息的嵌套JSON?(C#实现)
问题描述
我通过SQL查询得到一个DataTable,想要将其转换为指定结构的嵌套JSON文档。尝试过嵌套Dictionary但层级不足,也试过dynamic参数,刚接触C#不确定做法是否正确。另外需要在JSON顶部添加配置文件中手动输入的头部信息,该信息不在DataTable内。
示例DataTable
| database | table | tablesize | column | datatype |
|---|---|---|---|---|
| marketing | contacts | 535MB | contactid | int |
| marketing | contacts | 535MB | contact_firstname | varchar(50) |
| marketing | contacts | 535MB | contact_lastname | varchar(50) |
| marketing | addresses | 1200MB | addressid | int |
| marketing | addresses | 1200MB | address1 | varchar(100) |
| HR | employees | 600MB | employeeID | int |
| HR | employees | 600MB | employee_firstname | varchar(50) |
预期JSON结构
REQUESTED_BY: bob smith REQUEST_DATE: 12/30/2022 08:30 COMPLETED_BY: jane doe COMPLETED_ON: 12/30/2022 08:55 Databases: marketing tables: contacts tablesize:535MB columns: contactid datatype: int contact_firstname datatype: varchar(50) contact_lastname datatype: varchar(50) addresses tablesize:1200MB columns: addressid datatype: int address1 datatype: varchar(100) HR tables: employees tablesize:600MB columns: employeeid datatype: int employee_firstname datatype: varchar(50)
现有代码片段
var tbls = new Dictionary<string, Dictionary<string,string>>(); foreach (DataRow row in dbrequestdt.Rows) { string table = row["table"].ToString(); Dictionary<string, string> columns; if(!tbls.TryGetValue(table, out columns)) { columns = new Dictionary<string, string>(); tbls.Add(table, columns); } columns.Add(row["column"].ToString(), row["datatype"].ToString()); }
解决方案
使用强类型类映射嵌套结构比Dictionary更清晰易维护,后续修改也更方便,步骤如下:
1. 定义层级数据类
根据预期结构创建对应的数据类:
// 报告头部信息类 public class ReportHeader { public string REQUESTED_BY { get; set; } public DateTime REQUEST_DATE { get; set; } public string COMPLETED_BY { get; set; } public DateTime COMPLETED_ON { get; set; } public List<DatabaseInfo> Databases { get; set; } = new List<DatabaseInfo>(); } // 数据库信息类 public class DatabaseInfo { public string Name { get; set; } public List<TableInfo> Tables { get; set; } = new List<TableInfo>(); } // 表信息类 public class TableInfo { public string Name { get; set; } public string TableSize { get; set; } public List<ColumnInfo> Columns { get; set; } = new List<ColumnInfo>(); } // 列信息类 public class ColumnInfo { public string Name { get; set; } public string DataType { get; set; } }
2. 转换DataTable到类实例
遍历DataTable,按数据库、表分组填充数据:
// 从配置文件读取头部信息,替换为实际配置值 var reportHeader = new ReportHeader { REQUESTED_BY = "bob smith", REQUEST_DATE = DateTime.Parse("12/30/2022 08:30"), COMPLETED_BY = "jane doe", COMPLETED_ON = DateTime.Parse("12/30/2022 08:55") }; // 按数据库分组处理 var dbGroups = dbrequestdt.AsEnumerable() .GroupBy(row => row["database"].ToString()); foreach (var dbGroup in dbGroups) { var dbInfo = new DatabaseInfo { Name = dbGroup.Key }; // 每个数据库下按表分组 var tableGroups = dbGroup.GroupBy(row => row["table"].ToString()); foreach (var tableGroup in tableGroups) { var tableInfo = new TableInfo { Name = tableGroup.Key, TableSize = tableGroup.First()["tablesize"].ToString() // 同表的tablesize一致,取第一行即可 }; // 填充列信息 foreach (var row in tableGroup) { tableInfo.Columns.Add(new ColumnInfo { Name = row["column"].ToString(), DataType = row["datatype"].ToString() }); } dbInfo.Tables.Add(tableInfo); } reportHeader.Databases.Add(dbInfo); }
3. 序列化为JSON
使用System.Text.Json序列化(也可使用Newtonsoft.Json):
using System.Text.Json; var jsonOptions = new JsonSerializerOptions { WriteIndented = true, // 格式化输出,和示例结构对齐 PropertyNamingPolicy = null // 保留属性原名称,不自动转驼峰 }; string finalJson = JsonSerializer.Serialize(reportHeader, jsonOptions);
内容的提问来源于stack exchange,提问作者user1603398
相关产品推荐
相关产品推荐

