我正在使用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);
。但这会附加索引,并且需要提前知道列数。
答案 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;
});
}
}