CsvHelper:将集合读/写为重复的CSV列

时间:2019-04-30 23:59:40

标签: c# csv csvhelper

我正在使用CsvHelper,并且希望能够以重复列的形式读取/写入集合。例如,给定:

public class MyCsv
{
   public string A { get; set; }
   public List<string> Bs { get; set; }
}

var csv = new MyCsv { A = "a", Bs = new List { "b1", "b2" } };

我希望csv被序列化(使用CsvHelper)为:

A,B,B
a,b1,b2

然后我需要能够再次使用CsvHelper读取序列化的CSV。

这里要注意的是,我需要它成为不公开CsvHelper的平台的一部分,因此解决方案不能是例如WriteField的调用序列。 需要使用ClassMap完成此操作,以便消费者可以提供对象和自定义ClassMap。因此解决方案是定义一个ClassMap然后像这样使用CsvHelper

csvWriter.Configuration.RegisterClassMap(myMap);
csvWriter.WriteRecords(myObject);

我尝试将自定义ClassMap与自定义映射一起使用,例如:Map(m => m.Bs).Name("B").Index(0, 1);。但这会附加索引,并且需要提前知道列数。

1 个答案:

答案 0 :(得分:0)

我相信我有ClassMap可供阅读。但是我想不出一种方法来创建ClassMap来编写符合您要求的文字。

public static void Main(string[] args)
{
    using (MemoryStream stream = new MemoryStream())
    using (StreamWriter writer = new StreamWriter(stream))
    using (StreamReader reader = new StreamReader(stream))
    using (CsvReader csv = new CsvReader(reader))
    {
        writer.WriteLine("A,B,B");
        writer.WriteLine("a,b1,b2");
        writer.Flush();
        stream.Position = 0;

        var myMap = new MyCsvMap();

        csv.Configuration.RegisterClassMap(myMap);

        var records = csv.GetRecords<MyCsv>().ToList();
    }    
}

public class MyCsv
{
    public string A { get; set; }
    public List<string> Bs { get; set; }
}

public class MyCsvMap : ClassMap<MyCsv>
{
    public MyCsvMap()
    {
        Map(m => m.A);
        Map(m => m.Bs).ConvertUsing(row => {
            var result = new List<string>();
            var headers = row.Context.HeaderRecord;
            for (var i = 0; i < headers.Length; i++)
            {
                if (headers[i] == "B")
                {
                    result.Add(row.GetField(i));
                }
            }
            return result;
        });
    }
}