6

解析 csv 文件时,我如何定义特定字段是强制性的。本质上,我想确保给定的字段永远不会为空,如果是,那么我希望抛出异常。这是映射类:

public sealed class DataMapper : CsvClassMap<DataType>
{
    public DataMapper()
    {
        Map(m => m.Field1).Name("FirstField");
        Map(m => m.Field2).Name("SecondField");
        Map(m => m.Field3).Name("ThirdField"); // this field should be mandatory
    }
}

和用法:

List<DataType> data;
using (var sr = new StreamReader(localFilePath))
{
    var reader = new CsvReader(sr);
    reader.Configuration.RegisterClassMap<DataMapper>();
    data = reader.GetRecords<DataType>().ToList();
}

目前我只是检查数据列表中的结果如下:

var numberOfInvalidRecords = data.Count(data => string.IsNullOrEmpty(data.Field3));
if (nullAccountHolderRecords > 0)
{
    //handle
}

我无法在 CSVHelper 文档中找到内置功能。我错过了什么吗?

4

4 回答 4

5

我可能会使用ConvertUsing扩展名来做到这一点:

public sealed class DataMapper : CsvClassMap<DataType>
{
    public DataMapper()
    {
        Map(m => m.Field1).Name("FirstField");
        Map(m => m.Field2).Name("SecondField");
        Map(m => m.Field3).ConvertUsing(row =>
        {
            if(string.IsNullOrEmpty(row.GetField<string>("ThirdField")))
                throw new Exception("Oops, ThirdField is empty!");
            return row.GetField<string>("ThirdField");
        });
    }
}
于 2014-11-03T11:20:31.950 回答
5

这是一个扩展 API 的解决方案:

public static class CsvHelperExtensions
{
    public static CsvPropertyMap Required<T>(this CsvPropertyMap map, string columnName)
    {
        return map.Name(columnName).ConvertUsing(row =>
        {
            if (string.IsNullOrEmpty(row.GetField(columnName)))
                throw new CsvParserException($"{columnName} is required, but missing from row {row.Row}");
            return row.GetField<T>(columnName);
        });
    }
}

用法:

public CsvPersonMap()
{
    Map(m => m.FirstName).Required<string>("First");
    Map(m => m.LastName).Name("Last");
    Map(m => m.MiddleName).Required<string>("Middle");
}
于 2017-06-08T04:45:23.907 回答
3

开发人员现在添加了一个 Validate 方法:https ://joshclose.github.io/CsvHelper/examples/configuration/class-maps/validation

使用它来验证非空或空字符串:

Map(m => m.Id).Validate(field => !string.IsNullOrEmpty(field));

https://github.com/JoshClose/CsvHelper/issues/556

于 2019-09-11T15:49:19.163 回答
2

正如 CsvHelper 的创建者在这里所建议的

目前,我认为您必须拥有 WillThrowOnMissingField = false 并运行一个循环并检查您的特定必填字段。您可能可以在第一次阅读后检查标题。

他的示例代码:

csv.WillThrowOnMissingField = false;
var list = new List<MyObject>();
var headerChecked = false;
while( csv.Read() )
{
    if( !headerChecked )
    {
        // check for specific headers
        if( !csv.FieldHeaders.Exists( "MyHeaderName" ) )
        {
            throw new Exception( "message" );
        }
        headerChecked = true;
    }

    list.Add( csv.GetRecord<MyObject>() );
}
于 2014-11-03T11:12:58.560 回答