C# 合并两个具有不同方案和 return 层次 json 的数据表
C# Merge two datatable with different scheme and return hierarchical json
我有一个动态的数据表,可以有 5-10 列。在下面的示例中,我只显示了 4 列。
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Name");
dataTable.Columns.Add("America");
dataTable.Columns.Add("Japan");
dataTable.Columns.Add("Singapore");
dataTable.Rows.Add("A", 200, 100, 300);
dataTable.Rows.Add("B", 300, 300, 600);
dataTable.Rows.Add("C", 400, 400, 700);
dataTable.Rows.Add("D", 500, 500, 800);
dataTable.Rows.Add("E", 600, 600, 900);
dataTable.Rows.Add("F", 700, 700, 1000);
dataTable.Rows.Add("G", 800, 800, 600);
dataTable.Rows.Add("H", 900, 100, 400);
dataTable.Rows.Add("I", 100, 200, 300);
dataTable.Rows.Add("J", 200, 300, 200);
dataTable.Rows.Add("K", 300, 500, 500);
此数据表保证有 Name
列,其他列可能出现也可能不出现。
我有一个映射数据表,它也有 Name
列(可用于连接两个数据表),它还有另外两列建立行之间的关系。
DataTable mappingTable = new DataTable();
mappingTable.Columns.Add("Name");
mappingTable.Columns.Add("id");
mappingTable.Columns.Add("parentID");
mappingTable.Rows.Add("A", 1, null);
mappingTable.Rows.Add("B", 2, 1);
mappingTable.Rows.Add("C", 3, 1);
mappingTable.Rows.Add("D", 4, null);
mappingTable.Rows.Add("E", 5, 4);
mappingTable.Rows.Add("F", 6, null);
mappingTable.Rows.Add("G", 7, 6);
mappingTable.Rows.Add("H", 8, 6);
mappingTable.Rows.Add("I", 9, 1);
mappingTable.Rows.Add("J", 10, null);
mappingTable.Rows.Add("K", 11, 10);
目前我正在 returning JSON DataTable 使用:
var json = Newtonsoft.Json.JsonConvert.SerializeObject(dataTable);
它产生以下输出:
[
{
"name": "A",
"america": "200",
"japan": "100",
"singapore": "300"
},
{
"name": "B",
"america": "300",
"japan": "300",
"singapore": "600"
},
{
"name": "C",
"america": "400",
"japan": "400",
"singapore": "700"
},
{
"name": "D",
"america": "500",
"japan": "500",
"singapore": "800"
},
{
"name": "E",
"america": "600",
"japan": "600",
"singapore": "900"
},
{
"name": "F",
"america": "700",
"japan": "700",
"singapore": "1000"
},
{
"name": "G",
"america": "800",
"japan": "800",
"singapore": "600"
},
{
"name": "H",
"america": "900",
"japan": "100",
"singapore": "400"
},
{
"name": "I",
"america": "100",
"japan": "200",
"singapore": "300"
},
{
"name": "J",
"america": "200",
"japan": "300",
"singapore": "200"
},
{
"name": "K",
"america": "300",
"japan": "500",
"singapore": "500"
}
]
但不是 return 这种 JSON,我需要使用 Mapping DataTable 并在行和 return 之间建立关系 JSON 看起来像这个:
[{
"name": "A",
"america": "200",
"japan": "100",
"singapore": "300",
"children": [{
"name": "B",
"america": "300",
"japan": "300",
"singapore": "600"
}, {
"name": "C",
"america": "400",
"japan": "400",
"singapore": "700"
}, {
"name": "I",
"america": "100",
"japan": "200",
"singapore": "300"
}
]
}, {
"name": "D",
"america": "500",
"japan": "500",
"singapore": "800",
"children": [{
"name": "E",
"america": "600",
"japan": "600",
"singapore": "900"
}
]
}, {
"name": "F",
"america": "700",
"japan": "700",
"singapore": "1000",
"children": [{
"name": "G",
"america": "800",
"japan": "800",
"singapore": "600"
}, {
"name": "H",
"america": "900",
"japan": "100",
"singapore": "400"
}
]
}, {
"name": "J",
"america": "200",
"japan": "300",
"singapore": "200",
"children": [{
"name": "K",
"america": "300",
"japan": "500",
"singapore": "500"
}
]
}
]
DataTable 的结构可以更改,因为我可能会获得更多或更少的列数。如何生成所需的 JSON 输出?
我不确定是否有使用 DataTable 关系执行此操作的优雅方法。如果您不能摆脱使用数据表,您可以手动将数据映射到您需要的结构中。这假设映射 table 中的 ID 始终与数据 table.
中的行号匹配
var data = dataTable.Rows.Cast<DataRow>()
.Select(r => dataTable.Columns.Cast<DataColumn>().ToDictionary(c => c.ColumnName, c => r[c.ColumnName]))
.ToList();
var mapping = mappingTable.Rows.Cast<DataRow>()
.Where(r => !r["parentID"].Equals(DBNull.Value))
.ToLookup(r => (int)r["parentID"], r => (int)r["id"]);
var output = new List<Dictionary<string, Object>>();
foreach (var group in mapping) {
data[group.Key - 1].Add("children", group.Select(c => data[c - 1]).ToList());
output.Add(data[group.Key - 1]);
}
var json = Newtonsoft.Json.JsonConvert.SerializeObject(output);
我有一个动态的数据表,可以有 5-10 列。在下面的示例中,我只显示了 4 列。
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Name");
dataTable.Columns.Add("America");
dataTable.Columns.Add("Japan");
dataTable.Columns.Add("Singapore");
dataTable.Rows.Add("A", 200, 100, 300);
dataTable.Rows.Add("B", 300, 300, 600);
dataTable.Rows.Add("C", 400, 400, 700);
dataTable.Rows.Add("D", 500, 500, 800);
dataTable.Rows.Add("E", 600, 600, 900);
dataTable.Rows.Add("F", 700, 700, 1000);
dataTable.Rows.Add("G", 800, 800, 600);
dataTable.Rows.Add("H", 900, 100, 400);
dataTable.Rows.Add("I", 100, 200, 300);
dataTable.Rows.Add("J", 200, 300, 200);
dataTable.Rows.Add("K", 300, 500, 500);
此数据表保证有 Name
列,其他列可能出现也可能不出现。
我有一个映射数据表,它也有 Name
列(可用于连接两个数据表),它还有另外两列建立行之间的关系。
DataTable mappingTable = new DataTable();
mappingTable.Columns.Add("Name");
mappingTable.Columns.Add("id");
mappingTable.Columns.Add("parentID");
mappingTable.Rows.Add("A", 1, null);
mappingTable.Rows.Add("B", 2, 1);
mappingTable.Rows.Add("C", 3, 1);
mappingTable.Rows.Add("D", 4, null);
mappingTable.Rows.Add("E", 5, 4);
mappingTable.Rows.Add("F", 6, null);
mappingTable.Rows.Add("G", 7, 6);
mappingTable.Rows.Add("H", 8, 6);
mappingTable.Rows.Add("I", 9, 1);
mappingTable.Rows.Add("J", 10, null);
mappingTable.Rows.Add("K", 11, 10);
目前我正在 returning JSON DataTable 使用:
var json = Newtonsoft.Json.JsonConvert.SerializeObject(dataTable);
它产生以下输出:
[
{
"name": "A",
"america": "200",
"japan": "100",
"singapore": "300"
},
{
"name": "B",
"america": "300",
"japan": "300",
"singapore": "600"
},
{
"name": "C",
"america": "400",
"japan": "400",
"singapore": "700"
},
{
"name": "D",
"america": "500",
"japan": "500",
"singapore": "800"
},
{
"name": "E",
"america": "600",
"japan": "600",
"singapore": "900"
},
{
"name": "F",
"america": "700",
"japan": "700",
"singapore": "1000"
},
{
"name": "G",
"america": "800",
"japan": "800",
"singapore": "600"
},
{
"name": "H",
"america": "900",
"japan": "100",
"singapore": "400"
},
{
"name": "I",
"america": "100",
"japan": "200",
"singapore": "300"
},
{
"name": "J",
"america": "200",
"japan": "300",
"singapore": "200"
},
{
"name": "K",
"america": "300",
"japan": "500",
"singapore": "500"
}
]
但不是 return 这种 JSON,我需要使用 Mapping DataTable 并在行和 return 之间建立关系 JSON 看起来像这个:
[{
"name": "A",
"america": "200",
"japan": "100",
"singapore": "300",
"children": [{
"name": "B",
"america": "300",
"japan": "300",
"singapore": "600"
}, {
"name": "C",
"america": "400",
"japan": "400",
"singapore": "700"
}, {
"name": "I",
"america": "100",
"japan": "200",
"singapore": "300"
}
]
}, {
"name": "D",
"america": "500",
"japan": "500",
"singapore": "800",
"children": [{
"name": "E",
"america": "600",
"japan": "600",
"singapore": "900"
}
]
}, {
"name": "F",
"america": "700",
"japan": "700",
"singapore": "1000",
"children": [{
"name": "G",
"america": "800",
"japan": "800",
"singapore": "600"
}, {
"name": "H",
"america": "900",
"japan": "100",
"singapore": "400"
}
]
}, {
"name": "J",
"america": "200",
"japan": "300",
"singapore": "200",
"children": [{
"name": "K",
"america": "300",
"japan": "500",
"singapore": "500"
}
]
}
]
DataTable 的结构可以更改,因为我可能会获得更多或更少的列数。如何生成所需的 JSON 输出?
我不确定是否有使用 DataTable 关系执行此操作的优雅方法。如果您不能摆脱使用数据表,您可以手动将数据映射到您需要的结构中。这假设映射 table 中的 ID 始终与数据 table.
中的行号匹配var data = dataTable.Rows.Cast<DataRow>()
.Select(r => dataTable.Columns.Cast<DataColumn>().ToDictionary(c => c.ColumnName, c => r[c.ColumnName]))
.ToList();
var mapping = mappingTable.Rows.Cast<DataRow>()
.Where(r => !r["parentID"].Equals(DBNull.Value))
.ToLookup(r => (int)r["parentID"], r => (int)r["id"]);
var output = new List<Dictionary<string, Object>>();
foreach (var group in mapping) {
data[group.Key - 1].Add("children", group.Select(c => data[c - 1]).ToList());
output.Add(data[group.Key - 1]);
}
var json = Newtonsoft.Json.JsonConvert.SerializeObject(output);