真正的动态C#对象-使用<n>个属性(和动态属性名)旋转数据

时间:2019-02-08 15:35:07

标签: c# json dynamic expandoobject

对于我所缺少的这个问题,有一个很好的解决方案。我正在寻找的似乎非常简单,但我还没有找到一种方法来实现这一目标。

我有以下对象:

internal class OverrideValue
{
    public int RID { get; set; }
    public int PID { get; set; }
    public string Value { get; set; }
}

给定的RID可以具有多个PID /值组合。我需要使用JSON将动态创建(并命名)的列表返回给客户端。因此,给出以下内容:

var overrideList = new List<OverrideValue>()
{
    new OverrideValue() {RID = 1, PID = 1, Value = "200"},
    new OverrideValue() {RID = 1, PID = 2, Value = "250"},
    new OverrideValue() {RID = 2, PID = 1, Value = "200"},
    new OverrideValue() {RID = 2, PID = 3, Value = "300"},
    new OverrideValue() {RID = 2, PID = 4, Value = "255"}
};

我需要返回一个这样的对象:

{ "overrides":[
    { "RID":1, "PID_1":"200", "PID_2":"250" },
    { "RID":2, "PID_1":"200", "PID_3":"300", "PID_4":"255" }
]}

如果我的数据库返回的PID为400,000,则我需要该对象包含一个名为“ PID_4000000 ”的属性,并具有一个关联的值。

我意识到类型安全是C#的重要组成部分,但是对于这种情况,我不得不手动构造JSON似乎很荒谬。似乎应该为我提供一个内置方法来创建动态对象。我曾尝试过使用ExpandoObject(),但设法给我的是Dictionary()键/值对的列表,这是毫无用处的-序列化时,属性为“键”和“值”。

这归结为我使用的网格仅绑定到平面(一维)JSON数据源,并且我需要使用碰巧遇到的任何数据来构建网格。

2 个答案:

答案 0 :(得分:1)

这有点棘手,但应该给您足够的能力来满足您的需求。它使用Linq对值进行分组,并使用字典来存储分组的项目。

首先,我们需要一个包装器类来正确匹配您的输出:

const fs = require('fs');
const request = require('request');
const progress = require('request-progress');
const StreamZip = require('node-stream-zip');

// download large file...
const url = 'example.com/path/to/large/file';
const zipPath = 'generateATmpFileName.zip';
const jsonPath = 'generateATmpFileName.json';
progress(request(url))
    .on('end', function () {
        // file has been completely downloaded, lets unzip it
        var zip = new StreamZip({  
            file: zipPath,  
            storeEntries: true    
        });
        zip.on('ready', function() {
            zip.stream('path-to-json-file-in-zip.json', function(error, zstream) {
                zstream.pipe(fs.createWriteStream(jsonPath));
                zstream.on('end', function() { 
                    zip.close();
                    // file has been completely extracted, do what you want with it
                });
            });
        });
    })
    .pipe(fs.createWriteStream(zipPath));

现在我们可以将您的数据分组:

public class Output
{
    public IEnumerable<Dictionary<string, int>> Overrides { get; set; }
}

这将产生如下输出:

//Grou pand aggregate the data
var results = overrideList
    .GroupBy(l => l.RID)
    .Select(l =>
    {
        var dictionary = new Dictionary<string, int>();
        dictionary.Add("RID", l.Key);
        foreach (var pidValue in l)
        {
            dictionary.Add($"PID_{pidValue.PID}", int.Parse(pidValue.Value));
        }
        return dictionary;
    });

//Throw the data into our output class
var output = new Output
{
    Overrides = results
};

//Convert to JSON
var json = JsonConvert.SerializeObject(output);

答案 1 :(得分:0)

在查看如何保存数据时,此json表示不是默认表示,因为您将多个列表条目组合为1个单个组合条目。

我建议使用Jsom序列化程序,该序列化程序允许您定义应解析的属性/功能。然后实现一个返回字典列表的函数,该字典将列表条目组合为相应的组合条目。然后让序列化器序列化该函数的输出,就可以完成。

您可以使用此类:Json.NET JSONConvertor