将 CsvHelper 自定义转换器应用于一组 类 的所有字符串属性

Apply CsvHelper custom converter to all string properties of a set of classes

我正在使用 Josh Close 出色的 CsvHelper 库来读取 csv 文件并使用 entity framework 将它们加载到数据库中。除了一件事,这一切都很好; CsvReader 在 csv 文件中存储一个空字符串作为数据库中的一个空字符串,我希望它是一个 NULL 值。所以我所做的是创建一个自定义转换器来处理这个问题:

public class NullStringConverter : StringConverter
{
    public override object ConvertFromString(TypeConverterOptions options, string text)
    {
        if (string.IsNullOrEmpty(text))
            return null;
        else
            return base.ConvertFromString(options, text);
    }
}

我可以通过使用流畅的映射语法或通过属性将其应用于字符串 属性,它现在将插入 NULL 而不是空字符串。

因为我有很多 classes 包含许多字符串属性,所以我想避免为每个属性创建 Map 语句。我创建了一个通用 Map class,它枚举所有属性并将自定义转换器应用于所有字符串属性。这是我目前所拥有的

public class DefaultStringMap<TEntity> : CsvClassMap<TEntity> where TEntity : AbstractAmtSourceEntity
{
    public DefaultStringMap()
    {
        typeof(TEntity).GetProperties()
            .Where(p => p.PropertyType == typeof(string))
            .ToList()
            .ForEach(p => Map(m => p.Name).TypeConverter<NullStringConverter>());
    }
}

这里 AbstractAmtSourceEntity 是我所有实体 class 的基础 class。这是我实际获取数据的 reader class:

public static void Read<TEntity>(TextReader reader, AmtSourceModel context) where TEntity : AbstractAmtSourceEntity { using (var csvReader = new CsvReader(reader)) { csvReader.Configuration.WillThrowOnMissingField = false; csvReader.Configuration.Delimiter = "|"; csvReader.Configuration.SkipEmptyRecords = true; csvReader.Configuration.RegisterClassMap<DefaultStringMap<Entity1>>(); csvReader.Configuration.RegisterClassMap<DefaultStringMap<Entity2>>(); etc... csvReader.Configuration.IgnoreReadingExceptions = true; csvReader.Configuration.ReadingExceptionCallback = (ex, row) => { _log.Warn($"Exception caught reading row {row}", ex); _log.Debug($"Exception detail: {ex.Data["CsvHelper"]}"); }; var records = csvReader.GetRecords<TEntity>(); context.Set<TEntity>().AddRange(records); context.SaveChanges(); } } 但是,这不起作用,未应用映射,所以显然我遗漏了一些东西。谁能告诉我这里缺少什么?

您可以全局设置转换器。

TypeConverterFactory.AddConverter( typeof( string ), new NullStringConverter() );
// or
TypeConverterFactory.AddConverter<string>( new NullStringConverter() );