使用 CsvHelper 库,如何将空字段读取为 null 而不是空字符串?

Ale*_*lec 5 .net c# type-conversion csvhelper

我正在使用Josh Close 的CsvHelper库。

我想配置 CsvReader 将空字段转换为 null 而不是空字符串,目的是将这些值存储在数据库中。

值得注意的是,我没有映射到类,而是手动读取字段。

尝试:

  1. 我尝试将 CsvConfiguration.UseNewObjectForNullReferenceMembers 设置为 false(默认为 true),认为这可能意味着它在找到空字段时不会创建“新字符串对象”。
  2. 我尝试添加一个扩展 TypeConversion.StringConverter 并覆盖 ConvertFromString 方法的自定义类型转换器。
  3. 我尝试向 CsvConfiguration.TypeConverterOptions.getOptions.NullValues 添加空字符串。
CsvConfiguration csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture);

//csvConfiguration.UseNewObjectForNullReferenceMembers = false;
//csvConfiguration.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("");
//csvConfiguration.TypeConverterCache.AddConverter<string>(new NullStringConverter());

using (StreamReader streamReader = new StreamReader(fileStream))
using (CsvReader csv = new CsvReader(streamReader, csvConfiguration))
{
    string value = csv.GetField(index); // <-- I want this to be null not ""
}
Run Code Online (Sandbox Code Playgroud)
public class NullStringConverter : StringConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        if (string.IsNullOrEmpty(text))
        {
            return null;
        } 
        else
        {
            return base.ConvertFromString(text, row, memberMapData);
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lec 7

关键是我使用了 CsvReader 的 GetField 函数的错误重载。事后看来,在阅读函数描述的差异时,这一点有些明显,但我认为这很容易被忽视,因此希望这可以在将来帮助其他人,因为本质上类似的其他问题并没有让我得到这个答案。

前:

string value = csv.GetField(index); // Gets the raw field
Run Code Online (Sandbox Code Playgroud)

后:

string value = csv.GetField<string>(index); // Gets the field converted to a string
Run Code Online (Sandbox Code Playgroud)

StringConverter 似乎并不默认使用 null 而不是空字符串,因此我还需要使用最初尝试中的选项 2 或 3 来更改配置。选项 2 似乎更简单,所以这就是我采用的解决方案。

CsvConfiguration csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture);

csvConfiguration.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("");

using (StreamReader streamReader = new StreamReader(fileStream))
using (CsvReader csv = new CsvReader(streamReader, csvConfiguration))
{
    string value = csv.GetField<string>(index); // Yay this returns null!
}
Run Code Online (Sandbox Code Playgroud)

  • 对于当前版本 (v30.0.1),“TypeConverterOptionsCache”不再位于“CsvConfiguration”中。而是使用阅读器的 `Context` 属性,如下所示: `csv.Context.TypeConverterOptionsCache.GetOptions&lt;string&gt;().NullValues.Add("");` (6认同)