Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C合并两个具有不同方案的数据表并返回分层json_C#_.net_Linq_Datatable_Hierarchy - Fatal编程技术网

C# C合并两个具有不同方案的数据表并返回分层json

C# C合并两个具有不同方案的数据表并返回分层json,c#,.net,linq,datatable,hierarchy,C#,.net,Linq,Datatable,Hierarchy,我有一个数据表,它是动态的,可以有5-10列。在下面的示例中,我只显示了4列 DataTable dataTable = new DataTable(); dataTable.Columns.Add("Name"); dataTable.Columns.Add("America"); dataTable.Columns.Add("Japan"); dataTable.Columns.Add("Sing

我有一个数据表,它是动态的,可以有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);
保证此datatable必须命名列,其他列可能会出现,也可能不会出现

我有一个映射DataTable,它也有Name列,可以用来连接两个DataTable&它还有另外两个列,用于建立行之间的关系

 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);
目前,我正在使用以下命令从DataTable返回JSON:

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"
  }
]
但我需要使用Mapping DataTable并建立行之间的关系,而不是返回这种JSON,并返回一个分层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关系来实现这一点。如果无法摆脱使用DataTables,可以手动将数据映射到所需的结构中。这假设映射表中的ID始终与数据表中的行号匹配

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

听起来您需要将某些对象与列表/词典一起使用。将数据库中的数据加载到这些对象而不是数据表中可能需要另一种结构来表示数据。您不能使用类,因为您的记录具有动态结构。所以我想那本字典的目录可以帮你。一个人由一个属性字典表示,其中一个属性是子属性。然后您需要一个逻辑将数据转储到其中。@T.S.列的结构编号没有固定,这就是我决定使用DataTable的原因。@Leonardoneringer:您所说的有道理,但这意味着我需要更改大量现有代码。只有在找不到任何替代解决方案的情况下,我才会选择该路线。映射表中使用的ID是否始终与第一个表中的行号匹配?我必须做的唯一更改是将数据类型添加到MappingDataTable。mappingTable.Columns.AddName,TypeOfsString;mappingTable.Columns.Addid,typeOfint;mappingTable.Columns.AddparentID,typeOfint;