使用CsvHelper解析文件,该文件具有类之外的其他字段/属性

时间:2019-04-12 18:17:29

标签: c# csvhelper

我需要解析大部分映射到特定类的传入CSV文件。但是,如果客户愿意,则允许客户在记录的末尾添加额外的“用户定义”字段。因此,CSV可能类似于:

Id,FirstName,LastName,MyExtraField1,MyExtraField2
1,John,Doe,foo,bar
2,Jane,Smith,foo2,bar2

我的班级已经为Id,FirstName和LastName命名了属性,但没有为MyExtraField1和MyExtraField2命名。

如果我在名为“ ExtraFields”的类上创建了一个新的Dict属性,是否可以将CSV中与该类不匹配的任何字段都放入该字段并将其填充到ExtraFields词典中?关键字将是标题中字段的名称,然后是该记录的值。还是有其他方法可以捕获这些未映射到类中任何属性的字段?

1 个答案:

答案 0 :(得分:1)

我相信这能满足您的需求。

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("Id,FirstName,LastName,MyExtraField1,MyExtraField2");
        writer.WriteLine("1,John,Doe,foo,bar");
        writer.WriteLine("2,Jane,Smith,foo2,bar2");
        writer.Flush();
        stream.Position = 0;

        csv.Read();
        csv.ReadHeader();
        var headers = csv.Context.HeaderRecord.ToList();

        csv.Configuration.RegisterClassMap(new TestClassMap(headers.Skip(3)));

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

public class TestClass
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Dictionary<string, string> ExtraFields { get; set; }
}

public sealed class TestClassMap : ClassMap<TestClass>
{
    public TestClassMap(IEnumerable<string> headers)
    {
        Map(m => m.Id);
        Map(m => m.FirstName);
        Map(m => m.LastName);
        Map(m => m.ExtraFields).ConvertUsing(row => headers.ToDictionary(h => h, h => row.GetField(h)));
    }
}