Converting a DataTable to nested JSON output

北慕城南 提交于 2019-12-11 09:13:34

问题


I have a SQL Server source table defined as:

 sku    store  qty
 20000  100    3
 20000  132    1
 20000  320    0
 30000  243    2
 30000  210    1
 10000  410    5

I need the output to be:

{
  "skus": {
    "20000": {
      "100": 3,
      "132": 1,
      "320": 0
    },
    "30000": {
      "243": "2",
      "410": "1"
    },
    "10000": {
      "410": "5"
    }
  }
}

I have the source SQL Server table being imported to a DataSet, then was going to use JSON.NET to parse the results. I was thinking I should create some sort of Class structure with a sku having a list of store/qty key/value pairs, but I'm not totally sure if that's the right track or not.


回答1:


You're on the right track. To get the structure you outlined in your question, you need to use a dictionary of dictionaries representing mappings of store number to quantity per SKU. The class would look like this:

class RootObject
{
    [JsonProperty("skus")]
    public Dictionary<string, Dictionary<string, int>> Skus { get; set; }
}

You will need a small amount of code to group your data table rows into the nested dictionaries, as shown below. Note: this code assumes that each store number will be encountered only once per SKU. If this is not the case, you will need to adjust it accordingly.

DataTable table = new DataTable();
table.Columns.Add("sku", typeof(int));
table.Columns.Add("store", typeof(int));
table.Columns.Add("qty", typeof(int));
table.Rows.Add(20000, 100, 3);
table.Rows.Add(20000, 132, 1);
table.Rows.Add(20000, 320, 0);
table.Rows.Add(30000, 243, 2);
table.Rows.Add(30000, 210, 1);
table.Rows.Add(10000, 410, 5);

var skus = new Dictionary<string, Dictionary<string, int>>();

foreach (DataRow row in table.Rows)
{
    string sku = row["sku"].ToString();
    Dictionary<string, int> stores;
    if (!skus.TryGetValue(sku, out stores))
    {
        stores = new Dictionary<string, int>();
        skus.Add(sku, stores);
    }
    stores.Add(row["store"].ToString(), (int)row["qty"]);
}

RootObject root = new RootObject { Skus = skus };

Once you have the data gathered into your RootObject, it is trivial to serialize it to JSON using Json.Net:

string json = JsonConvert.SerializeObject(root, Formatting.Indented);

Deserializing the JSON back to your RootObject is just as easy:

RootObject root = JsonConvert.DeserializeObject<RootObject>(json);

Here is a full round-trip demo: https://dotnetfiddle.net/qR3wbE




回答2:


Right now you have values as keys , because JSON is meant to group your records by objects. I recommend you to change your JSON to the following, which will make it easier to work with

{
    "skus": [
        {
            "sku": 20000,
            "store": 100,
            "qty": 1
        },
        {
            "sku": 20000,
            "store": 132,
            "qty": 0
        }
    ]
}

Model:

public class Sku
{
    public int sku { get; set; }
    public int store { get; set; }
    public int qty { get; set; }
}

public class RootObject
{
    public List<Sku> skus { get; set; }
}

Parse JSON to C# Objects

var skusObjects =  JsonConvert.DeserializeObject<RootObject>(json);

foreach (var item in skusObjects.skus)
{   
    Console.WriteLine(item.sku);
}

Output

20000
20000
30000
30000
10000

DEMO




回答3:


You can do select form the table using linq-to-sql and do groupby and put the data in to object that you have defined before which have the structure that you described after that you can deserialize and send back as json



来源:https://stackoverflow.com/questions/26752368/converting-a-datatable-to-nested-json-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!