提问人:G J 提问时间:1/12/2022 最后编辑:G J 更新时间:1/13/2022 访问量:396
不会为嵌套集合生成 CSVHelper 标头
CSVHelper headers wont get generated for nested collection
问:
尝试将列表转换为CSV文件,我在其中嵌套了集合。
当 CSV 读入对象集合时,转换可以完美工作,但当使用相同的集合使用相同的映射生成 CSV 时,不会生成所有标头。无法弄清楚我做错了什么,生成除名为列的集合之外的所有列,例如.Children, GrandChildren
using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.TypeConversion;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Xunit;
namespace CSVHelperNugetHierarchyTest
{
class Program
{
static List<Parent> Parents;
static List<string> Headers;
static void Main(string[] args)
{
using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(GetCSV())))
{
using (var reader = new StreamReader(stream))
{
using (var csv = new CsvReader(reader, new CsvConfiguration(CultureInfo.GetCultureInfo("en-US")) { HasHeaderRecord = true }))
{
csv.Context.TypeConverterCache.AddConverter<List<Child>>(new ChildrenConverter());
csv.Context.TypeConverterCache.AddConverter<List<GrandChild>>(new GrandChildrenConverter());
csv.Context.RegisterClassMap<ParentMapper>();
csv.Context.RegisterClassMap<ChildMapper>();
csv.Context.RegisterClassMap<GrandChildMapper>();
Parents = csv.GetRecords<Parent>().ToList();
Headers = csv.HeaderRecord.ToList();
}
}
}
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
using (var csv = new CsvWriter(writer, new CsvConfiguration(CultureInfo.GetCultureInfo("en-US")) { HasHeaderRecord = true }))
{
csv.Context.TypeConverterCache.AddConverter<List<Child>>(new ChildrenConverter());
csv.Context.TypeConverterCache.AddConverter<List<GrandChild>>(new GrandChildrenConverter());
csv.Context.RegisterClassMap<ParentMapper>();
csv.Context.RegisterClassMap<ChildMapper>();
csv.Context.RegisterClassMap<GrandChildMapper>();
csv.WriteRecords(Parents);
}
}
var streamBuffer = stream.ToArray();
var content = Encoding.UTF8.GetString(streamBuffer);
foreach (var item in Headers)
{
Assert.Contains(item, content);
}
}
}
static string GetCSV()
{
return "Property0,Property1,Property2,Property3,Property4"
+ Environment.NewLine
+ "a,b,c,d,e";
}
}
class Parent
{
public string Property0 { get; set; }
public string Property1 { get; set; }
public List<Child> Children { get; set; }
}
class Child
{
public string Property2 { get; set; }
public string Property3 { get; set; }
public List<GrandChild> GrandChildren { get; set; }
}
class GrandChild
{
public string Property4 { get; set; }
}
class ParentMapper : ClassMap<Parent>
{
public ParentMapper()
{
Map(m => m.Property0);
Map(m => m.Property1);
Map(m => m.Children).Index(0);
}
}
class ChildMapper : ClassMap<Child>
{
public ChildMapper()
{
Map(m => m.Property2);
Map(m => m.Property3);
Map(m => m.GrandChildren).Index(0);
}
}
class GrandChildMapper : ClassMap<GrandChild>
{
public GrandChildMapper()
{
Map(m => m.Property4);
}
}
class ChildrenConverter : ITypeConverter
{
public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
var children = new List<Child>();
children.Add(row.GetRecord<Child>());
return children;
}
public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
var children = value as List<Child>;
foreach (var child in children)
{
row.WriteRecord(child);
}
return null;
}
}
class GrandChildrenConverter : ITypeConverter
{
public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
var children = new List<GrandChild>();
children.Add(row.GetRecord<GrandChild>());
return children;
}
public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
var children = value as List<GrandChild>;
foreach (var child in children)
{
row.WriteRecord(child);
}
return null;
}
}
}
收到的输出:
Property0,Children,Property1
a,c,e,d,b
预期输出:
Property0,Property1,Property2,Property3,Property4
a,b,c,d,e
我在 .NET Core 3.1 环境中使用 CsvHelper 版本。27.2.1
尝试了很多方法,例如将列、索引和列 + 索引一起添加。
PS:省略了一些空检查和验证。
答: 暂无答案
评论
List<Child>
List<Grandchild>
;
Children
GrandChildren
List<Child>
List<Grandchild>
;
GrandChildren
Child
GrandChildren