【问题标题】:Write an object with a List<T> field to CSV将具有 List<T> 字段的对象写入 CSV
【发布时间】:2019-11-22 01:02:26
【问题描述】:

我正在学习 C# 和对象序列化。我需要将对象保存在 .csv 文件中。我尝试了CsvHelper,但找不到我的问题的答案。

假设我有一个这样的对象:

public class Record
{
    ...
    public List<string> Collection { get; set; }
    ...
}

如何使用CsvHelperCollection 的值与 csv 文件记录中的其他原始类型一起存储在 .csv 文件中?

【问题讨论】:

  • 当您按照 CSVHelper 的教程进行操作时,发生了什么? joshclose.github.io/CsvHelper/…
  • CSV 是平面文件格式;除非您制定某种自定义方案,否则它不支持嵌入式类型。编写 CSV 文件非常容易;你为什么不写一些代码来做呢?
  • @RobertHarvey 不想开始大辩论,但为了安东的利益,我不想让你的陈述完全不受质疑。编写 CSV 可能听起来很容易,但由于需要转义逗号和内引号等,这看起来很棘手。不要尝试重新发明轮子并创建自己的 CSV 编写器 - 坚持使用现有的库来处理你的细微差别。
  • 不管怎样,问题是没有产生输出;问题是定义输出应该是什么样子。 CSVHelpers 不会在这方面提供任何帮助。
  • @AntonIugov - 我们能澄清一下吗。您真的需要将其保存为 CSV 吗? CSV 是一种平面格式,它并非真正设计用于存储嵌套信息。也许如果您更新了问题以解释您究竟需要什么 - 以及您认为它应该是什么样子 - 我们可以更好地帮助您:)

标签: c# csv csvhelper


【解决方案1】:

CsvHelper 默认会忽略集合。但是,使用ClassMap,您可以使用Index 来指示您想要一个简单的字符串集合与其他属性一起输出。 (没有很好的记录。)

public class Program
{
    public static void Main(string[] args)
    {
        var records = new List<Record>
        {
            new Record { Id = 1, Name = "Record1", Collection = new List<string>{"First", "Second", "Third"}},
            new Record { Id = 2, Name = "Record2", Collection = new List<string>{"First", "Second"}},
        };

        using (var csv = new CsvWriter(Console.Out))
        {
            csv.Configuration.HasHeaderRecord = false;
            csv.Configuration.RegisterClassMap<RecordMap>();

            csv.WriteRecords(records);
        }

        Console.ReadKey();
    }

}

public class RecordMap : ClassMap<Record>
{
    public RecordMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
        Map(m => m.Collection).Index(3);
    }
}

public class Record
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<string> Collection { get; set; }
}

输出:

1,Record1,First,Second,Third
2,Record2,First,Second

如果您知道集合中的最大项目数,您还可以设置结束索引并让CsvHelper 为每个集合项目创建标题。

public class RecordMap : ClassMap<Record>
{
    public RecordMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
        Map(m => m.Collection).Index(3, 5);
    }
}

删除csv.Configuration.HasHeaderRecord = false;,现在它还会为您打印标题记录。 输出:

Id,Name,Collection1,Collection2,Collection3
1,Record1,First,Second,Third
2,Record2,First,Second

【讨论】:

  • 在上面的例子中,列出作为新列输出的数据,是否可以将它们写入新行(行中,有/没有)与其他常见列的重复,例如:1,Record1,First /n 1, Record1, Second /n 1, Record1, 第三 /n 2, Record2, Frist /n 2, Record2, Second ?
  • @Vitalii 可以,但必须手动编写。 foreach (var record in records){ foreach (var item in record.Collection){ csv.WriteRecord(record); csv.WriteField(item); csv.NextRecord(); }} 同时删除 RegisterClassMap&lt;RecordMap&gt;()
猜你喜欢
  • 2012-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
相关资源
最近更新 更多