将 CsvHelper 自定义转换器应用于一组类的所有字符串属性
Posted
技术标签:
【中文标题】将 CsvHelper 自定义转换器应用于一组类的所有字符串属性【英文标题】:Apply CsvHelper custom converter to all string properties of a set of classes 【发布时间】:2017-01-17 11:07:57 【问题描述】:我正在使用 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】:您可以全局设置转换器。
TypeConverterFactory.AddConverter( typeof( string ), new NullStringConverter() );
// or
TypeConverterFactory.AddConverter<string>( new NullStringConverter() );
【讨论】:
超级棒,这就是我要找的。span> StringConverter 的全局覆盖在最新版本 (2.16.3) 中对我不起作用。如果我如问题中所述明确指定转换器,则可以正常工作。 请注意,从 3.0 版开始,TypeConverterFactory
现在称为 TypeConverterCache
,可从您的 CsvReader
实例访问,例如reader.Configuration.TypeConverterCache
。 Reference以上是关于将 CsvHelper 自定义转换器应用于一组类的所有字符串属性的主要内容,如果未能解决你的问题,请参考以下文章