C#-动态添加对象(添加动态属性名称)

C#-动态添加对象(添加动态属性名称),c#,json,dynamic,structure,expandoobject,C#,Json,Dynamic,Structure,Expandoobject,我正在尝试创建一些动态的ExpandoObject。我遇到了一个问题 由于我不知道对象中这些不同属性的名称,我不能这样做: var list = new ArrayList(); var obj = new ExpandoObject(); obj.ID = 1, obj.Product = "Pie", obj.Days = 1, obj.QTY = 65 list.Add(obj); 让我解释一下我的情况:我希望从一个随机数据库中获取数据(我不知道是哪个数据库,但根据我从UI获取的信息

我正在尝试创建一些动态的
ExpandoObject
。我遇到了一个问题

由于我不知道对象中这些不同属性的名称,我不能这样做:

var list = new ArrayList();

var obj = new ExpandoObject();
obj.ID = 1,
obj.Product = "Pie",
obj.Days = 1,
obj.QTY = 65

list.Add(obj);
让我解释一下我的情况:我希望从一个随机数据库中获取数据(我不知道是哪个数据库,但根据我从UI获取的信息构建一个连接字符串),因此我不知道需要获取什么数据。这可能是DB表的一个示例

桌面销售

  • ID:int
  • 产品:nvarchar(100),
  • 天数:int
  • 数量:bigint
这可能是另一个exmaple:

表Foobar

  • Id:int
  • 天数:整数
  • 数量:bigint
  • 产品编号:int
  • 部门编号:int
如您所见,我不知道DB是什么样子(这是100%匿名的,因此它需要100%动态),我想要返回的数据应该看起来像一个构造良好的JSON,如下所示:

[
  {
    "ID": 1,
    "Product": "Pie"
    "Days": 1,
    "QTY": 65
  },
  {
    "ID": 2,
    "Product": "Melons"
    "Days": 5,
    "QTY": 12
  }
]
或者,举另一个例子:

[
  {
    "ID": 1,
    "Days": 2,
    "QTY": 56,
    "Product_Id": 5,
    "Department_Id": 2
  }
  {
    "ID": 2,
    "Days": 6,
    "QTY": 12,
    "Product_Id": 2,
    "Department_Id": 5
  }
]
我尝试过使用这些
ExpandoObject
s,但似乎无法使其正常工作,因为我无法完成问题顶部的说明(我不知道属性的名称)。我有没有办法说这样的话:

var obj = new ExpandoObject();
var propName = "Product";

var obj.propName = "Pie"

Console.WriteLine("Let's print!: " + obj.Product);

//OUTPUT
Let's print!: Pie

是否有人有一个解决方案,即对结构的指导,可以解决这种情况?

您可以创建一个
列表,其中每个
字典
都包含要序列化的名称/值对,而不是创建一个
扩展对象
或其他动态类型。然后使用(或者,尽管灵活性较低),序列化为JSON:

第二个输出相同,没有缩进:

正如您在这里看到的,
ExpandoObject
正在实现
IDictionary
,因此您可以像这样使用这个事实

IDictionary<string, object> obj = new ExpandoObject();
var propName = "Product";
obj[propName] = "Pie"
Console.WriteLine("Let's print!: " + obj[propName]);
// Verify it's working
Console.WriteLine("Let's print again!: " + ((dynamic)obj).Product);
IDictionary obj=new ExpandoObject();
var propName=“产品”;
obj[propName]=“饼图”
Console.WriteLine(“让我们打印!:”+obj[propName]);
//验证它是否正常工作
WriteLine(“让我们再次打印:”+((动态)obj.Product);
第一部分,由C#团队彻底阅读

让我们看看你的代码

var obj = new ExpandoObject();
var propName = "Product";

var obj.propName = "Pie"

Console.WriteLine("Let's print!: " + obj.Product);

//OUTPUT
Let's print!: Pie
在代码中,您使用的是
var obj=new ExpandoObject(),因此您正在创建类型为
ExpandableObject
的静态类型对象。在博客中,他们特别呼吁

我没有编写ExpandoObject contact=new ExpandoObject(),因为如果我这样做,contact将是ExpandoObject类型的静态类型对象。当然,静态类型变量不能在运行时添加成员。因此,我使用了新的dynamic关键字而不是类型声明,而且由于ExpandooObject支持动态操作,因此代码可以正常工作

因此,如果您将代码重写为使用
dynamic obj
,并将动态属性添加为应该工作的属性

但是对于您的特定用例,您最好使用@dbc建议的字典

dynamic obj = new ExpandoObject();
obj.Product= "Pie"    
Console.WriteLine("Let's print!: " + obj.Product);    
//OUTPUT
Let's print!: Pie

使用
dynamic
,然后强制转换到
IDictionary
以循环浏览您的属性:

dynamic obj = new ExpandoObject();
obj.Product = "Pie";
obj.Quantity = 2;

// Loop through all added properties       
foreach(var prop in (IDictionary<string, object>)obj)
{
  Console.WriteLine(prop.Key + " : " + prop.Value);
}
dynamic obj=new ExpandoObject();
obj.Product=“馅饼”;
目标数量=2;
//循环浏览所有添加的属性
foreach(在(IDictionary)obj中的var prop)
{
Console.WriteLine(属性键+”:“+属性值);
}
我做了一把小提琴:


现在这是你问题的解决方案。。。其他的答案,比如@dbc,可能更适合这个问题(其实这不是问题)

当我写答案时,我发现你已经得到了正确的答案。您可以使用
字典
甚至
元组

但根据您最初的问题,您希望动态添加属性。为此,您可以使用
ExpandoObject
参考其他答案。这是相同的解决方案(使用
ExpandoObject
动态添加属性),类与代码类似

//example classes
public class DictKey
{
    public string DisplayName { get; set; }
    public DictKey(string name) { DisplayName = name; }
}

public class DictValue
{
    public int ColumnIndex { get; set; }
    public DictValue(int idx) { ColumnIndex = idx; }
}

//utility method
public static IDictionary<string, object> GetExpando(KeyValuePair<DictKey, List<DictValue>> dictPair)
{
    IDictionary<string, object> dynamicObject = new ExpandoObject();
    dynamicObject["Station"] = dictPair.Key.DisplayName;
    foreach (var item in dictPair.Value)
    {
        dynamicObject["Month" + (item.ColumnIndex + 1)] = item;
    }
    return dynamicObject;
}
//示例类
公共类DictKey
{
公共字符串DisplayName{get;set;}
公钥(字符串名){DisplayName=name;}
}
公共阶级价值观
{
公共int列索引{get;set;}
公共值(int idx){ColumnIndex=idx;}
}
//实用方法
公共静态IDictionary GetExpando(KeyValuePair dictPair)
{
IDictionary dynamicObject=新的ExpandooObject();
dynamicObject[“Station”]=dictPair.Key.DisplayName;
foreach(dictPair.Value中的var项)
{
dynamicObject[“月”+(item.ColumnIndex+1)]=项目;
}
返回动态对象;
}
Ans使用示例:

var dictionaryByMonth = new Dictionary<DictKey, List<DictValue>>();
dictionaryByMonth.Add(new DictKey("Set1"), new List<DictValue> { new DictValue(0), new DictValue(2), new DictValue(4), new DictValue(6), new DictValue(8) });
dictionaryByMonth.Add(new DictKey("Set2"), new List<DictValue> { new DictValue(1), new DictValue(2), new DictValue(5), new DictValue(6), new DictValue(11) });

var rowsByMonth = dictionaryByMonth.Select(item => GetExpando(item));
var Dictionary bymonth=new Dictionary();
dictionaryByMonth.Add(new DictKey(“Set1”)、新列表{new DictValue(0)、new DictValue(2)、new DictValue(4)、new DictValue(6)、new DictValue(8)});
dictionaryByMonth.Add(new DictKey(“Set2”)、新列表{new DictValue(1)、new DictValue(2)、new DictValue(5)、new DictValue(6)、new DictValue(11)});
var rowsByMonth=dictionaryByMonth.Select(item=>GetExpando(item));

您使用的是什么语言?您标记了C#,但您的一些代码是Java(即System.out.printline)-.NET没有这个。我没有复制粘贴任何代码。我就是记不起它在C中叫什么了。这是纯C#,没有别的。我道歉。只需创建一个
列表
,即可更正可能的重复项。如果您将其序列化为JSON,比如说,您将得到您想要的。@GSerg在我的情况下,
ExpandoObject
is:)不会真正起作用,因为我没有所有可用的值,但我需要遍历它们。你能举个例子吗
var valueList=allRowValues
var-Clunnames=AllClunnames
(编辑主要问题)如果您在创建字典@Detilium后无法获取数据,那么字典将非常无用。@dbc出于某种原因,我的Json看起来是这样的:
[{“ID\”:1,“Product\:“Honning\”,“Days\:1,\“QTY\”:65}]
@Detilium-在这个问题中没有提到邮递员
dynamic obj = new ExpandoObject();
obj.Product = "Pie";
obj.Quantity = 2;

// Loop through all added properties       
foreach(var prop in (IDictionary<string, object>)obj)
{
  Console.WriteLine(prop.Key + " : " + prop.Value);
}
//example classes
public class DictKey
{
    public string DisplayName { get; set; }
    public DictKey(string name) { DisplayName = name; }
}

public class DictValue
{
    public int ColumnIndex { get; set; }
    public DictValue(int idx) { ColumnIndex = idx; }
}

//utility method
public static IDictionary<string, object> GetExpando(KeyValuePair<DictKey, List<DictValue>> dictPair)
{
    IDictionary<string, object> dynamicObject = new ExpandoObject();
    dynamicObject["Station"] = dictPair.Key.DisplayName;
    foreach (var item in dictPair.Value)
    {
        dynamicObject["Month" + (item.ColumnIndex + 1)] = item;
    }
    return dynamicObject;
}
var dictionaryByMonth = new Dictionary<DictKey, List<DictValue>>();
dictionaryByMonth.Add(new DictKey("Set1"), new List<DictValue> { new DictValue(0), new DictValue(2), new DictValue(4), new DictValue(6), new DictValue(8) });
dictionaryByMonth.Add(new DictKey("Set2"), new List<DictValue> { new DictValue(1), new DictValue(2), new DictValue(5), new DictValue(6), new DictValue(11) });

var rowsByMonth = dictionaryByMonth.Select(item => GetExpando(item));