尝试使用 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
}
}
我有一个只有 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
}
}