【问题标题】:Read a list of dynamic objects into CSV将动态对象列表读入 CSV
【发布时间】:2014-06-05 17:13:21
【问题描述】:

我正在尝试将大量数据读入平面 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; }
}

然后我想使我的列表动态处理各种属性:

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);
        }

... 这也很好用。但现在我想基本上展平这个列表并将其导出为 CSV,因为我知道我的动态列表的每一行可能具有稍微不同的属性。

获取动态类型PropertyInfo,显然一无所获。我是否只需要遍历我的列表以手动将唯一属性提取到 DataTable 之类的东西中?或者我可以用反射打一些电话来更有效地完成这项工作?

【问题讨论】:

  • 您能否提供一个 responses 示例,其中包含两个不同的条目以及您希望 csv 的外观如何?您的 ExpandoObject fullResponse 中已经有 KeValuePairs 的属性和值。

标签: c# csv dynamic reflection


【解决方案1】:

我最终使用了一个普通的旧 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
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多