【问题标题】:Recursively serialize multiple Datatable hierarchies to JSON object递归地将多个 Datatable 层次结构序列化为 JSON 对象
【发布时间】:2016-01-24 21:02:48
【问题描述】:

我想将多个相互关联的 DataTable 序列化为 JSON,并且可能会在映射表中设置额外的表。在这种情况下,我有 3 个数据表。

  • 表 A 作为父表
  • 表 B 作为表 A 的子表
  • 表 C 作为表 B 的子表

JSON 输出应该是

{
    "TableA": [
        {
            "ID": "2490",
            "TYPE": "Electronic",
            "TableB": [
                {
                    "ID": "2490",
                    "ITEM": "XMT123",
                    "RECEIPT_NUM": "59",
                    "TableC": [
                        {
                            "ID": "2490",
                            "ITEM": "XMT123",
                            "QUANTITY": "164"
                        }
                    ]
                },
                {
                    "ID": "2491",
                    "ITEM": "XMT234",
                    "RECEIPT_NUM": "12",
                    "TableC": [
                        {
                            "ID": "2491",
                            "ITEM": "XMT234",
                            "QUANTITY": "92"
                        }
                    ]
                }
            ]
        },
        {
            "ID": "2491",
            "TYPE": "Electronic",
            "TableB": [
                {
                    "ID": "2491",
                    "ITEM": "XMT456",
                    "RECEIPT_NUM": "83",
                    "TableC": [
                        {
                            "ID": "2491",
                            "ITEM": "XMT456",
                            "QUANTITY": "261"
                        }
                    ]
                },
                {
                    "ID": "2492",
                    "ITEM": "XMT567",
                    "RECEIPT_NUM": "77",
                    "TableC": [
                        {
                            "ID": "2492",
                            "ITEM": "XMT567",
                            "QUANTITY": "70"
                        }
                    ]
                }
            ]
        }
    ]
}

我已经尝试过这样的代码,但它似乎不起作用

static void dataToJson(string connection_string, string query, string table_name)
{
    try
    {
        JArray jArray = new JArray();
        DataTable tbl = new DataTable();
        DataTable inner_tbl = new DataTable();
        SqlConnection conn = new SqlConnection(connection_string);
        conn.Open();
        var adapter = new SqlDataAdapter(query, conn); // query to get parent
        adapter.Fill(tbl);
        foreach (DataRow row in tbl.Rows)
        {
            JObject jo = new JObject();
            foreach (DataColumn col in tbl.Columns)
            {
                jo.Add(new JProperty(col.ColumnName.ToString(), row[col].ToString()));
            }
            jArray.Add(jo);

            query = "i have query to get child";
            dataToJson(connection_string, query, table_child);                  
        }
    }
    catch (Exception e)
    {
        WriteLog(e.Message, GetCurrentMethod(e));
    }
}

【问题讨论】:

    标签: c# json recursion datatable table-per-hierarchy


    【解决方案1】:

    您必须在此递归方法中传递父级或返回子级。此外,如果所有表都在同一个数据库中,您不必每次都打开SqlConnection
    以下是传递父级的示例:

    // Caller
    JObject root = new JObject();
    using (SqlConnection conn = new SqlConnection(connection_string))
    {
        conn.Open();
        dataToJson(root, conn, query, "TableA");
    }
    Console.WriteLine(root.ToString());
    
    
    static void dataToJson(JObject parent, SqlConnection conn, string query, string table_name)
    {
        if (string.IsNullOrEmpty(table_name)) { return; }
        try
        {
            JArray jArray = new JArray();
            DataTable tbl = new DataTable();
            //DataTable inner_tbl = new DataTable();
            //SqlConnection conn = new SqlConnection(connection_string);
            //conn.Open();
            var adapter = new SqlDataAdapter(query, conn); // query to get parent
            adapter.Fill(tbl);
            foreach (DataRow row in tbl.Rows)
            {
                JObject jo = new JObject();
                foreach (DataColumn col in tbl.Columns)
                {
                    jo.Add(new JProperty(col.ColumnName.ToString(), row[col].ToString()));
                }
                query = "i have query to get child";
                // Set the child table name to "table_child"
                dataToJson(jo, conn, query, table_child);  // Pass the JObject as the parent
    
                jArray.Add(jo); 
                parent.Add(new JProperty(table_name, jArray));
            }
        }
        catch (Exception e)
        {
            WriteLog(e.Message, GetCurrentMethod(e));
        }
    }
    

    顺便说一下,我不知道你是怎么得到子表的名字的,所以我用下面的字典来测试。

    static Dictionary<string, string> table_hierarchy = new Dictionary<string, string>();
    // Initialize
    table_hierarchy.Add("TableA", "TableB");
    table_hierarchy.Add("TableB", "TableC");
    table_hierarchy.Add("TableC", "");
    

    【讨论】:

    • TableA 上只有 2 条记录有效。 3 下一条记录出错。无法将属性 TableB 添加到 Newtonsoft.Json.Linq.JObject。对象上已存在同名属性。
    • 现在它运行良好,无一例外地捕捉到。非常感谢。
    • 感谢您将我的答案标记为最佳答案。如果我需要对此进行更新,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    相关资源
    最近更新 更多