【问题标题】:Nested JSON data to datatable dynamically C#将 JSON 数据动态嵌套到数据表 C#
【发布时间】:2020-07-09 05:25:11
【问题描述】:
{
    "STATUS": "OK",
    "projects": [
        {
            "startDate": "",
            "last-changed-on": "2019-01-03T11:46:14Z",
            "logo": "",
            "created-on": "2018-12-12T10:04:47Z",
            "privacyEnabled": false,
            "status": "active",
            "boardData": {},
            "replyByEmailEnabled": true,
            "harvest-timers-enabled": false,
            "description": "",
            "category": {
                "color": "",
                "id": "",
                "name": ""
            },
            "id": "322852",
            "overview-start-page": "default",
            "start-page": "projectoverview",
            "integrations": {
                "xero": {
                    "basecurrency": "",
                    "countrycode": "",
                    "enabled": false,
                    "connected": "NO",
                    "organisation": ""
                },
                "sharepoint": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                },
                "microsoftConnectors": {
                    "enabled": false
                },
                "onedrivebusiness": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                }
            },
            "defaults": {
                "privacy": ""
            },
            "notifyeveryone": false,
            "filesAutoNewVersion": false,
            "defaultPrivacy": "open",
            "tasks-start-page": "default",
            "starred": false,
            "announcementHTML": "",
            "isProjectAdmin": true,
            "name": "Project 2",
            "company": {
                "is-owner": "1",
                "id": "78494",
                "name": "MCG Company"
            },
            "endDate": "",
            "announcement": "",
            "show-announcement": false,
            "subStatus": "current",
            "tags": []
        },
        {
            "startDate": "",
            "last-changed-on": "2018-12-11T17:52:57Z",
            "logo": "",
            "created-on": "2018-11-26T11:11:00Z",
            "privacyEnabled": false,
            "status": "active",
            "boardData": {},
            "replyByEmailEnabled": true,
            "harvest-timers-enabled": false,
            "description": "",
            "category": {
                "color": "",
                "id": "",
                "name": ""
            },
            "id": "321041",
            "overview-start-page": "default",
            "portfolioBoards": [
                {
                    "card": {
                        "id": "4771"
                    },
                    "board": {
                        "id": "544",
                        "name": "Project Implementations",
                        "color": "#F39C12"
                    },
                    "column": {
                        "id": "1573",
                        "name": "Go Live",
                        "color": "#F1C40F"
                    }
                }
            ],
            "start-page": "projectoverview",
            "integrations": {
                "xero": {
                    "basecurrency": "",
                    "countrycode": "",
                    "enabled": false,
                    "connected": "NO",
                    "organisation": ""
                },
                "sharepoint": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                },
                "microsoftConnectors": {
                    "enabled": false
                },
                "onedrivebusiness": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                }
            },
            "defaults": {
                "privacy": ""
            },
            "notifyeveryone": false,
            "filesAutoNewVersion": false,
            "defaultPrivacy": "open",
            "tasks-start-page": "default",
            "starred": false,
            "announcementHTML": "",
            "isProjectAdmin": true,
            "name": "Project One",
            "company": {
                "is-owner": "1",
                "id": "78494",
                "name": "MCG Company"
            },
            "endDate": "",
            "announcement": "",
            "show-announcement": false,
            "subStatus": "current",
            "tags": []
        }
    ]
}

这是我从应用程序获取的 JSON 响应,还有许多其他 API 获取返回相同类型的响应(嵌套),因此必须在用户添加时动态完成来自配置文件的 API 调用,因此我无法使用获取和设置制作预制类。 我的目标是将这些数据转换为要插入数据库的数据表 当我看到一个嵌套列时,我的目标是使用“_”附加父列名称,例如:category_id = “” 或 integrations_xero_basecurrency = "" 等。

这是我用来将数据制成表格的代码,但在代码中,只有当它是 JValue(键和值)时才会使用该列,而且我无法终生创建适当的循环这样就可以了。

    public DataTable Tabulate(string jsonContent)
    {
        var jsonLinq = JObject.Parse(jsonContent);

        // Find the first array using Linq
        var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
        //Console.WriteLine("extarcted data:" + srcArray);
        var trgArray = new JArray();
        foreach (JObject row in srcArray.Children<JObject>())
        {
            var cleanRow = new JObject();
            foreach (JProperty column in row.Properties())
            {
                // Only include JValue types
                if (column.Value is JValue)
                {
                    cleanRow.Add(column.Name, column.Value);
                }
            }

            trgArray.Add(cleanRow);
        }

        DataTable dt = JsonConvert.DeserializeObject<DataTable>(trgArray.ToString());            

        return dt;
    }

【问题讨论】:

    标签: c# json datatable json.net


    【解决方案1】:

    这样的事情怎么样:

    public DataTable Tabulate(string jsonContent)
    {
        var jsonLinq = JObject.Parse(jsonContent);
    
        // Find the first array using Linq
        var arrayProp = jsonLinq.Properties().First(p => p.Value is JArray);
        var srcArray = (JArray)arrayProp.Value;
    
        // Set up a regex consisting of the array property name and subscript 
        // (e.g. "projects[0]."), which we will strip off
        var regex = new Regex($@"^{arrayProp.Name}\[\d+\]\.");
    
        // Flatten each object of the original array 
        // into new objects and put them in a new array 
        var trgArray = new JArray(
            srcArray.Children<JObject>()
                    .Select(row => new JObject(
                         row.Descendants()
                            .OfType<JProperty>()
                            .Where(p => p.Value is JValue)
                            .Select(p => new JProperty(
                                regex.Replace(p.Value.Path, "").Replace(".", "_"), 
                                p.Value
                            ))
                    ))
            );
    
        // Convert the new array to a DataTable
        DataTable dt = trgArray.ToObject<DataTable>();
    
        return dt;
    }
    

    工作演示:https://dotnetfiddle.net/yrmcSQ

    【讨论】:

    • 它在大多数情况下工作得非常完美,虽然其中的一些列是这样的,但使用 [0] 和 [1] 的portfolioBoards[0]_board_color
    • 我认为这发生在没有数据“portfolioBoards”的空文件上:[]
    • 我想知道您的 JSON 中是否包含任何数组,如果是,您将如何处理这些数组。您发布的示例没有 portfolioBoards 数组。
    • 请原谅我的无知,我是新手。你的问题是有效的,我没有考虑如何处理数组。正如我所看到的,我有两个选择,第一个是忽略它们(如果节点是数组类型则忽略),或者以与在列名中添加所有子项相同的方式处理它们,这将创建一个很多问题:列名会很大,数组中的节点重复等等。很想听听你的想法。我已经将portfolioBoards数组添加到上面的示例中。
    • 忽略它们是最简单的选择,但这取决于您是否真的需要这些数据。如果您确实需要它,那么您必须决定如何捕获它。一种想法是将子数据表存储在具有数组的列中。因此,例如,主列将是 portfolioBoards,它将包含一个 DataTable,其中每行包含 card_idboard_idboard_nameboard_color 等列。但是,如果您的目标是将所有内容插入数据库,那么这将无济于事,因为您将无法在数据库的表中存储表。
    猜你喜欢
    • 2014-03-28
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    相关资源
    最近更新 更多