这是我的代码,无法正确加载数据,该文件存在,因为标头确实将标头的实际值存储在CSV文件中。
textReader = new StreamReader(importBookingsFilePath.Text);
string firstLine = textReader.ReadLine();
List<string> headers = SplitCSV(firstLine).ToList();
var csv = new CsvReader(textReader, CultureInfo.InvariantCulture);
if (headers.Count == 77 || headers.Count == 86)
csv.Configuration.RegisterClassMap<CSVBookingMapNonPayment>();
else if (headers.Count == 78 || headers.Count == 91)
csv.Configuration.RegisterClassMap<CSVBookingMapPayment>();
else if (headers.Count == 79 && (headers.Contains("IP") || headers.Contains("\"IP\"")))
csv.Configuration.RegisterClassMap<CSVBookingMapNonPaymentExtraIPInfo>();
else if (headers.Count == 74)
csv.Configuration.RegisterClassMap<CSVBookingMapNonPayment_DaySail>();
else if (headers.Count == 87)
csv.Configuration.RegisterClassMap<CSVBookingMapNonPayment_Group>();
else if (headers.Count == 93)
csv.Configuration.RegisterClassMap<CSVBookingMap_Payment_Crew>();
var records = csv.GetRecords<CSVBooking>().ToList();
我确实在CSVBooking类中添加了索引,而映射类确实指向了索引。每当我运行代码“ records”都没有价值。
您正在从TextReader
中读取一行,然后将同一TextReader
传递到CsvReader
中。这意味着CsvReader
将开始读取TextReader
所在的位置,这是第二行。它会将第一行视为标题行,并将其与注册的地图匹配。在您的情况下,那是一个数据行,而不是标题。
我的建议是立即注册所有地图。每当调用GetRecord<MyType>
时,它将使用该类型的注册映射。您可以根据需要在一行上读取几种类型,或者每行读取另一种类型。
[在CsvHelper中执行操作的方式如下所示。
void Main()
{
var s = new StringBuilder();
s.AppendLine("Id,Name");
s.AppendLine("1,one");
s.AppendLine("2,two");
using (var reader = new StringReader(s.ToString()))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Read();
csv.ReadHeader();
if (csv.Context.HeaderRecord.Length == 2)
{
csv.Configuration.RegisterClassMap<FooMap>();
}
else if (csv.Context.HeaderRecord.Length == 3)
{
csv.Configuration.RegisterClassMap<BarMap>();
}
csv.GetRecords<Foo>().ToList().Dump();
}
}
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Bar
{
public Guid Property1 { get; set; }
public decimal Cost { get; set; }
public DateTimeOffset Date { get; set; }
}
public class FooMap : ClassMap<Foo>
{
public FooMap()
{
Map(m => m.Id);
Map(m => m.Name);
}
}
public class BarMap : ClassMap<Bar>
{
public BarMap()
{
Map(m => m.Property1);
Map(m => m.Cost);
Map(m => m.Date);
}
}
同样,我建议仅注册所有地图,而不使用if
语句。
您想使用CsvHelper阅读第一行的另一个原因是,字段中可能会有换行符。如果发生这种情况,通过TextReader
读取一行将无法获得完整的CSV行。