Добавление обнаруживаемых значений Nullable в CsvHelper

Мне было интересно, если CsvHelper Джоша Клоуз имеет что-то в конфигурации, я пропускаю, чтобы перевести значения в ноль. Я большой поклонник этой библиотеки, но я всегда думал, что должна быть какая-то конфигурация, чтобы она знала, какие значения представляют NULL в вашем файле. Примером может служить столбец со значениями "NA", "EMPTY", "NULL" и т. Д. Я уверен, что мог бы создать свой собственный TypeConverter, но я надеялся, что будет более простой вариант для установки где-нибудь в конфигурации как это обычно встречается в файлах, с которыми я сталкиваюсь.

Есть ли настройки конфигурации, чтобы сделать это относительно легко?

Я нашел TypeConversion в пространстве имен CsvHelper.TypeConversion, но не уверен, где применить что-то подобное или пример правильного использования:

new NullableConverter(typeof(string)).ConvertFromString(new TypeConverterOptions(), "NA")

Я также использую последнюю версию 2.2.2

Спасибо!

1 ответ

Решение

CsvHelper может обрабатывать типы, допускающие обнуление. Вам не нужно накатывать свой собственный TypeConverter, если пустой столбец считается пустым. Для моих примеров я предполагаю, что вы используете пользовательские беглые отображения.

Первое, что вам нужно сделать, это построить CsvHelper.TypeConverter объект для ваших Nullable типов. Обратите внимание, что я собираюсь использовать int поскольку строки допускают нулевые значения по умолчанию.

public class MyClassMap : CsvClassMap<MyClass>
{
     public override CreateMap()
     {
          CsvHelper.TypeConversion.NullableConverter intNullableConverter = new CsvHelper.TypeConversion.NullableConverter(typeof(int?));

          Map(m => m.number).Index(2).TypeConverter(intNullableConverter);
      }
 }

Далее следует установить атрибут в вашем объекте CsvReader, чтобы разрешить пустые столбцы и автоматически обрезать поля. Лично нравится делать это, создавая CsvConfiguration объект со всеми моими настройками до создания моего CsvReader объект.

CsvConfiguration csvConfig = new CsvConfiguration();
csvConfig.RegisterClassMap<MyClassMap>();
csvConfig.WillThrowOnMissingField = false;
csvConfig.TrimFields = true;

Тогда вы можете позвонить myReader = new CsvReader(stream, csvConfig) построить CsvReader объект.

Если вам нужно определить значения для нуля, такие как "NA" == null тогда вам нужно будет свернуть свой собственный CsvHelper.TypeConversion учебный класс. Я рекомендую вам продлить NullableConverter класс, чтобы сделать это и переопределить как конструктор и ConvertFromString метод. Использование пустых значений в качестве нулевого значения действительно является лучшим выбором.

Я думаю, что когда-то за последние семь лет и в тринадцати версиях с тех пор, как был задан этот вопрос, варианты для этого без расширения класса карты пользовательского типа, например:

csvReader.Configuration.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("NULL");
csvReader.Configuration.TypeConverterOptionsCache.GetOptions<DateTime?>().NullValues.AddRange(new[] { "NULL", "0" });
csvReader.Configuration.TypeConverterOptionsCache.GetOptions<int?>().NullValues.Add("NULL");
csvReader.Configuration.TypeConverterOptionsCache.GetOptions<bool>().BooleanFalseValues.Add("0");
csvReader.Configuration.TypeConverterOptionsCache.GetOptions<bool>().BooleanTrueValues.Add("1");

Я использовал "ConvertUsing"...

public class RecordMap : CsvHelper.Configuration.ClassMap<Record>
{
    public RecordMap()
    {
        AutoMap();
        Map(m => m.TransactionDate).ConvertUsing( NullDateTimeParser );
        Map(m => m.DepositDate).ConvertUsing( NullDateTimeParser );
    }

    public DateTime? NullDateTimeParser(IReaderRow row)
    {
        //"CurrentIndex" is a bit of a misnomer here - it's the index of the LAST GetField call so we need to +1
        //https://github.com/JoshClose/CsvHelper/issues/1168

        var rawValue = row.GetField(row.Context.CurrentIndex+1);

        if (rawValue == "NULL")
            return null;
        else
            return DateTime.Parse(rawValue);

    }
}
Другие вопросы по тегам