C# 将动态对象列表读入CSV

C# 将动态对象列表读入CSV,c#,csv,dynamic,reflection,C#,Csv,Dynamic,Reflection,我正在尝试将一个大的数据列表读入一个平面CSV。每行的一个字段是XML数据,XML在每行中指示其他属性。因此,每行的属性可能略有不同 我在最初的结构化课程中得到了我的列表: private class Response { public Response() { Values = new Dictionary<string, string>(); } public string Owner { get; set; } public s

我正在尝试将一个大的数据列表读入一个平面CSV。每行的一个字段是XML数据,XML在每行中指示其他属性。因此,每行的属性可能略有不同

我在最初的结构化课程中得到了我的列表:

private class Response {
    public Response() {
        Values = new Dictionary<string, string>();
    }

    public string Owner { get; set; }
    public string Author { get; set; }
    public string Email { get; set; }
    public string Data { get; set; } // XML data in here
    public Dictionary<string, string> Values { get; set; }
    public DateTime Created { get; set; }
}
私有类响应{
公众回应({
值=新字典();
}
公共字符串所有者{get;set;}
公共字符串作者{get;set;}
公共字符串电子邮件{get;set;}
公共字符串数据{get;set;}//XML数据在这里
公共字典值{get;set;}
已创建公共日期时间{get;set;}
}
然后,我想让我的列表动态化,以处理各种属性:

var responses = new List<dynamic>();
foreach (var response in query) {
    if (!string.IsNullOrEmpty(response.Data))
    {
        var doc = new XmlDocument();
        doc.LoadXml(response.Data);

        foreach (XmlNode node in doc.GetElementsByTagName("field")) {
        try
        {
            response.Values.Add(node.FirstChild.InnerText, node.LastChild.InnerText);
        }
        catch (Exception ex) {
            // log
        }
    }
}

            dynamic fullResponse = new ExpandoObject();
            fullResponse.Owner = response.Owner;
            fullResponse.Author = response.Author;
            fullResponse.Email = response.Email;
            fullResponse.Created = response.Created;

            IDictionary<string, object> map = fullResponse;
            foreach (var value in response.Values) {
                if (map.ContainsKey(value.Key)) {
                    map[value.Key] = value.Value;
                }
                else {
                    map.Add(value.Key, value.Value);
                }
            }

            responses.Add(fullResponse);
        }
var responses=newlist();
foreach(查询中的var响应){
如果(!string.IsNullOrEmpty(response.Data))
{
var doc=新的XmlDocument();
doc.LoadXml(response.Data);
foreach(doc.GetElementsByTagName(“字段”)中的XmlNode节点){
尝试
{
Add(node.FirstChild.InnerText,node.LastChild.InnerText);
}
捕获(例外情况除外){
//日志
}
}
}
dynamic fullResponse=新的ExpandooObject();
fullResponse.Owner=response.Owner;
fullResponse.Author=response.Author;
fullResponse.Email=response.Email;
fullResponse.Created=response.Created;
IDictionary map=完整响应;
foreach(响应中的var值.Values){
if(map.ContainsKey(value.Key)){
map[value.Key]=value.value;
}
否则{
map.Add(value.Key,value.value);
}
}
添加(fullResponse);
}
。。。这也很好用。但现在我想基本上展平这个列表,并将其导出为CSV,因为我知道动态列表的每一行可能有稍微不同的属性


抓取
属性info
,这是一种动态类型,显然会一无所获。我是否只需要在列表中循环以手动将唯一属性提取到类似DataTable的内容中?或者我可以通过反思打一些电话来更有效地完成这项工作

我最终使用了一个普通的旧数据表对其进行排序:

using (var dt = new DataTable())
{
     var keys = responses.SelectMany(x => ((IDictionary<string, object>)x).Keys).Distinct();
     var columns = keys.Select(x => new DataColumn(x)).ToArray();
     dt.Columns.AddRange(columns);

     foreach(IDictionary<string, object> response in responses)
     {
         var row = dt.NewRow();
         foreach (var kvp in response)
         {
             row[kvp.Key] = kvp.Value;
         }
         dt.Rows.Add(row);
     }

     // write to CSV
}
使用(var dt=new DataTable())
{
var keys=responses.SelectMany(x=>((IDictionary)x).keys.Distinct();
var columns=keys.Select(x=>newdatacolumn(x)).ToArray();
dt.Columns.AddRange(列);
foreach(响应中的索引响应)
{
var row=dt.NewRow();
foreach(var kvp响应)
{
行[kvp.Key]=kvp.Value;
}
dt.行。添加(行);
}
//写入CSV
}

虽然我觉得我可以用反射做一些更酷的事情来达到同样的效果。

你能提供一个例子,说明你的
回答有两个不同的条目,以及你希望你的csv是什么样子吗?
ExpandoObject fullResponse
中已经有了kevalue成对的属性和值。