CsvHelper - 验证整行
CsvHelper - validate whole row
问题
我最近开始学习更多关于 csvHelper 的知识,我需要有关如何实现我的目标的建议。
我有一个包含一些用户记录(数千到数十万条记录)的 CSV 文件,我需要解析该文件和 validate/process 数据。我需要做的是两件事:
我需要一种方法来在读取整行时验证它
- 记录包含日期范围,我需要验证它是有效范围
- 如果不是,我需要将有问题的行写入错误文件
一个记录也可以在不同的日期范围内多次出现,我需要验证范围是否重叠,如果重叠,请将整个原始行写入错误文件
我基本上可以得到的是一种将整个原始行与解析数据一起保存的方法,但是在原始数据仍然可用时验证整行的方法会更好。
问题
是否有一些 events/actions 隐藏在某处,我可以用来在数据行创建之后但在添加到集合之前对其进行验证?
如果没有,有没有办法将整个 RAW 行保存到记录中,这样我就可以在解析后验证该行,如果它无效,请执行我需要的操作?
我有代码
我创建的是这样的记录class:
class Record
{ //simplified and omitted fluff for brevity
string Login
string Domain
DateTime? Created
DateTime? Ended
}
和一张class地图:
class RecordMapping<Record>
{ //simplified and omitted fluff for brevity
public RecordMapping(ConfigurationElement config)
{
//..the set up of the mapping...
}
}
然后像这样使用它们:
public ProcessFile(...)
{
...
using(var reader = StreamReader(...))
using(var csvReader = new CsvReader(reader))
using(var errorWriter = new StreamWriter(...))
{
csvReader.Configuration.RegisterClassMap(new RadekMapping(config));
//...set up of csvReader configuration...
try
{
var records = csvReader.GetRecords<Record>();
}
catch (Exception ex)
{
//..in case of problems...
}
....
}
....
}
在这种情况下,从 CsvHelper 的角度来看,数据可能 "valid",因为它可以读取数据,但由于更复杂的原因(例如无效的日期范围)而无效。
在那种情况下,这可能是一个简单的方法:
public IEnumerable<Thing> ReadThings(TextReader textReader)
{
var result = new List<Thing>();
using (var csvReader = new CsvReader(textReader))
{
while (csvReader.Read())
{
var thing = csvReader.GetRecord<Thing>();
if (IsThingValid(thing))
result.Add(thing);
else
LogInvalidThing(thing);
}
}
return result;
}
如果您需要记录的是原始文本,那就是:
LogInvalidRow(csvReader.Context.RawRecord);
另一种选择——也许是更好的选择——可能是将验证与阅读完全分开。换句话说,只是阅读记录而不进行验证。
var records = csvReaader.GetRecords<Record>();
您的 reader class returns 他们不负责确定哪些有效
以及如何处理它们。
然后另一个 class 可以验证 IEnumerable<Record>
,返回有效行并记录无效行。
这样,验证和日志记录的逻辑就不会与读取代码捆绑在一起。如果您从 CSV 文件以外的其他文件中获取 Record
的集合,将更容易测试和重用。
问题
我最近开始学习更多关于 csvHelper 的知识,我需要有关如何实现我的目标的建议。
我有一个包含一些用户记录(数千到数十万条记录)的 CSV 文件,我需要解析该文件和 validate/process 数据。我需要做的是两件事:
我需要一种方法来在读取整行时验证它
- 记录包含日期范围,我需要验证它是有效范围
- 如果不是,我需要将有问题的行写入错误文件
一个记录也可以在不同的日期范围内多次出现,我需要验证范围是否重叠,如果重叠,请将整个原始行写入错误文件
我基本上可以得到的是一种将整个原始行与解析数据一起保存的方法,但是在原始数据仍然可用时验证整行的方法会更好。
问题
是否有一些 events/actions 隐藏在某处,我可以用来在数据行创建之后但在添加到集合之前对其进行验证?
如果没有,有没有办法将整个 RAW 行保存到记录中,这样我就可以在解析后验证该行,如果它无效,请执行我需要的操作?
我有代码
我创建的是这样的记录class:
class Record
{ //simplified and omitted fluff for brevity
string Login
string Domain
DateTime? Created
DateTime? Ended
}
和一张class地图:
class RecordMapping<Record>
{ //simplified and omitted fluff for brevity
public RecordMapping(ConfigurationElement config)
{
//..the set up of the mapping...
}
}
然后像这样使用它们:
public ProcessFile(...)
{
...
using(var reader = StreamReader(...))
using(var csvReader = new CsvReader(reader))
using(var errorWriter = new StreamWriter(...))
{
csvReader.Configuration.RegisterClassMap(new RadekMapping(config));
//...set up of csvReader configuration...
try
{
var records = csvReader.GetRecords<Record>();
}
catch (Exception ex)
{
//..in case of problems...
}
....
}
....
}
在这种情况下,从 CsvHelper 的角度来看,数据可能 "valid",因为它可以读取数据,但由于更复杂的原因(例如无效的日期范围)而无效。
在那种情况下,这可能是一个简单的方法:
public IEnumerable<Thing> ReadThings(TextReader textReader)
{
var result = new List<Thing>();
using (var csvReader = new CsvReader(textReader))
{
while (csvReader.Read())
{
var thing = csvReader.GetRecord<Thing>();
if (IsThingValid(thing))
result.Add(thing);
else
LogInvalidThing(thing);
}
}
return result;
}
如果您需要记录的是原始文本,那就是:
LogInvalidRow(csvReader.Context.RawRecord);
另一种选择——也许是更好的选择——可能是将验证与阅读完全分开。换句话说,只是阅读记录而不进行验证。
var records = csvReaader.GetRecords<Record>();
您的 reader class returns 他们不负责确定哪些有效 以及如何处理它们。
然后另一个 class 可以验证 IEnumerable<Record>
,返回有效行并记录无效行。
这样,验证和日志记录的逻辑就不会与读取代码捆绑在一起。如果您从 CSV 文件以外的其他文件中获取 Record
的集合,将更容易测试和重用。