使用 JSON.NET 从数据表创建 JSON

Create JSON from datatable using JSON.NET

我正在从数据库查询中获取数据表,我需要从中创建一个 JSON。 如果我使用 JSON.NET 对数据表进行直接序列化,我会得到以下结果,

[{"Item_CODE":"A08","ITEM_NAME":"sampleName","ITEM_LOCATION":"Kolkata"}]

不过我正在寻找以下 JSON 格式,

{
 "Codes": ["A08","A09","A10"],
 "ITEM_NAME": "sampleName",
 "ITEM_LOCATION": "Kolkata",
 }

我知道没有直接的方法可以做到这一点。那么我是否需要遍历数据表并动态创建 JSON ? 我正在查看 Automapper 库,并且很想知道是否可以那样做。 我如何为自动映射器映射 JSON?

一种可能的解决方案是使用自定义转换器并控制序列化 -

var settings = new JsonSerializerSettings();
settings.Converters.Add(new CustomConverter());
var json = JsonConvert.SerializeObject(o, settings);
// {"Codes":["A08","A09","A10"],"ITEM_NAME":"sampleName","ITEM_LOCATION":"Kolkata"}

internal class Product
{
    public List<string> Item_CODE { get; set; }
    public string ITEM_NAME { get; set; }
    public string ITEM_LOCATION { get; set; }
}

internal class CustomConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var data = value as DataTable;
        if (data != null)
        {
            var res = new Product
            {
                Item_CODE = new List<string>()
            };
            foreach (DataRow row in data.Rows)
            {
                res.Item_CODE.Add((string)row[0]);
                if (string.IsNullOrWhiteSpace(res.ITEM_NAME)) res.ITEM_NAME = (string)row[1]; ;
                if (string.IsNullOrWhiteSpace(res.ITEM_LOCATION)) res.ITEM_LOCATION = (string)row[2];
            }

            writer.WriteStartObject();
            writer.WritePropertyName("Codes");
            writer.WriteStartArray();
            res.Item_CODE.ForEach(a => writer.WriteValue(a));
            writer.WriteEndArray();
            writer.WritePropertyName("ITEM_NAME");
            writer.WriteValue(res.ITEM_NAME);
            writer.WritePropertyName("ITEM_LOCATION");
            writer.WriteValue(res.ITEM_LOCATION);
            writer.WriteEnd();
        }
    }
}