簡體   English   中英

CsvHelper:將集合讀/寫為重復的CSV列

[英]CsvHelper: Read/Write Collection as Repeated CSV Columns

我正在使用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); 但這會附加索引,並且需要提前知道列數。

我相信我有一個ClassMap可供閱讀。 但是我想不出一種方法來創建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;
        });
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM