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

时间:2016-09-09 10:14:55

标签: c# reflection csvhelper

我正在使用Josh Close优秀的CsvHelper库来读取csv文件并使用实体框架将它们加载到数据库中。这一切都很好,除了一件事; 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而不是空字符串。

由于我有很多包含许多字符串属性的类,所以我希望避免为每个人和每个人创建Map语句。我创建了一个通用的Map类,它枚举所有属性并将自定义转换器应用于所有字符串属性。这就是我所熟悉的

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是我所有实体类的基类。这是我的读者类实际获取数据:

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(); } }  但这不起作用,映射没有应用,所以很明显我错过了一些东西。谁能告诉我这里缺少什么?

1 个答案:

答案 0 :(得分:3)

您可以全局设置转换器。

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