尝试使用 CsvHelper 将 CSV 行解析为多个 类

Trying to parse CSV rows into multiple classes with CsvHelper

我有一个只有 Header 行的 CSV。每行的一些列需要映射到一个 class 而该行的其他列需要映射到不同的 class.

我试过了,但没有成功:

using(var reader = new StreamReader(@"c:\temp\myfile.csv"))
{
    using(var csv = new CsvReader(reader))
    {
       csv.Configuration.RegisterClassMap<ClientMap>();
       csv.Configuration.RegisterClassMap<BookingMap>();

       var bookings = csv.GetRecords<Booking>();
       ... //iterate over bookings and write to Console

       reader.BaseStream.Position = 0;

       var clients = csv.GetRecords<Client>();
       ... //iterate over clients and write to Console
    }
}

public class Client {
   public string Firstname {get; set;}
   public string Lastname {get; set;}
   public AgesEnum Age {get; set;}
}

public class Booking {
    public string ExternalId {get; set;}
    public string Status {get; set;}
}

地图

public class ClientMap : ClassMap<Client> 
{
   public ClientMap()
   {
       Map(m => m.Firstname).Name("FIRSTNAM");
       Map(m => m.Lastname).Name("LASTNAME");
       Map(m => m.Age).ConvertUsing(row =>{
          var age = row.GetField<int>("AGE");

          if(age < 2)
             return AgesEnum.Baby;
          if(age < 10)
             return AgesEnum.Young;
          if(age < 40)
             return AgesEnum.Middle;
          return AgesEnum.Old;
       } );
    }
}


public BookingMap : ClassMap<Booking>
{
    public BookingMap()
    {
        Map(b => b.ExternalId).Name("SYSID");
        Map(b => b.Status);
    }
}

当我 运行 时发生的事情是 bookings 得到很好的返回,我可以迭代它们。但是,我在 GetRecords<Client>() 行中收到一条错误消息,指出

The conversion cannot be performed. Text: 'Age' MemberType: TypeConverter: 'CsvHelper.TypeConversion.Int32Converter'

如果我注释掉所有与 Bookings 相关的代码并只执行 GetRecords<Client>(),我不会出错。

为什么这行不通?我必须设置一个全新的 StreamReader 吗?

我认为您可能会发现一些关于将枚举与 CsvHelper 结合使用的有趣内容

问题是您将流位置设置回开头,CsvReader 认为您在收到预订时已经阅读了 header,因此它再次读取第一行作为数据作为 header。您需要再次手动阅读header。

using(var reader = new StreamReader(@"c:\temp\myfile.csv"))
{
    using(var csv = new CsvReader(reader))
    {
       csv.Configuration.RegisterClassMap<ClientMap>();
       csv.Configuration.RegisterClassMap<BookingMap>();

       var bookings = csv.GetRecords<Booking>();
       ... //iterate over bookings and write to Console

       reader.BaseStream.Position = 0;

       csv.Read();
       csv.ReadHeader();

       var clients = csv.GetRecords<Client>();
       ... //iterate over clients and write to Console
    }
}