как обрабатывать нулевые значения для типа данных SQLDecimal в классах FileHelper

Я пытаюсь загрузить файл с помощью FileHelpers (как это уже было, за исключением этой одной проблемы: P). Мне нужно сохранить данные файла CSV в базу данных, поэтому я использую тип данных SqlDecimal для хранения десятичных значений файлов CSV.

[FileHelpers.FieldOptional()]
[FileHelpers.FieldConverter(typeof(SqlDecimalConverter))]
public SqlDecimal Rate;

Все это работает нормально, пока у меня не будет пустого значения для FixRate1. Это отмечено ошибкой.

«Предупреждение об исключении: для поля «Ставка» в классе «SWTrade» найдено нулевое значение. Вы должны указать атрибут FieldNullValueAttribute, поскольку это тип значения и не может быть нулевым.

Я попытался указать [FileHelpers.FieldNullValue(SqlDecimal.Null)], но это, очевидно, выдает ошибку.

Аргумент атрибута должен быть константным выражением, выражением typeof или выражением создания массива типа параметра атрибута.

Несмотря на то, что я переопределяю метод FieldToString в классе SqlDecimalConverter, функция не вызывается при чтении данных.

Ну, в таком случае, есть ли способ, которым я могу присвоить любое нулевое значение или даже какое-то другое жестко запрограммированное значение данным Rate, которые я могу затем заменить на нулевое значение непосредственно в моей собственной логике?

Пожалуйста, дайте мне знать, если вам понадобится дополнительная информация. Заранее спасибо.


person keepsmilinyaar    schedule 06.01.2010    source источник


Ответы (4)


Другие комментарии верны, вам нужно использовать

private decimal? internalRate;

А позже создайте свойство для преобразования, на самом деле библиотека только автопреобразует нативные типы, а SqlDecimal не один.

public SqlDecimal? Rate
{
    get 
    {
        if (internalRate.HasValue)
            return new SqlDecimal(internalRate.Value);
        else
            return null;
    }
}

PS: Если вы хотите перейти к пользовательскому конвертеру, чтобы использовать его для чтения, вам нужно переопределить метод StringToField (FieldToString вызывается для записи)

Надеюсь это поможет :)

person Marcos Meli    schedule 06.01.2010
comment
Удивительно, но функция FieldToString не вызывается, а файловый помощник напрямую выдает исключение. - person keepsmilinyaar; 11.01.2010
comment
Вы возвращаете значение SqlDecimal? Можете ли вы прислать мне код конвертера или вставить его здесь, чтобы проверить, что не так? Спасибо - person Marcos Meli; 11.01.2010

Вы можете попробовать использовать тип Nullable. Если вы используете тип Nullable, вам не нужно указывать атрибут FieldNullValue.

[FileHelpers.FieldConverter(typeof(SqlDecimalConverter))]
public SqlDecimal? Rate;

Этот подход отлично работает с DateTime, используя встроенный конвертер типов FileHelpers.

Если это не сработает, вы можете назначить значение по умолчанию, которое вы можете рассматривать как нулевое. Но это может быть проблематично, если есть фактическое значение, соответствующее выбранному значению по умолчанию:

[FieldNullValue(typeof(SqlDecimal), "-1")]
[FileHelpers.FieldConverter(typeof(SqlDecimalConverter))]
public SqlDecimal Rate;

Обновить

Я только что сделал тест и просто использовал десятичную дробь? тип работает нормально. Затем вы можете преобразовать его в свой код в правильный SqlType для доступа к базе данных. Я думаю, что это самый простой подход.

Таким образом, поле будет выглядеть так:

public decimal? Rate;

никаких атрибутов не требуется.

person Randy supports Monica    schedule 06.01.2010
comment
[FieldNullValue(typeof(SqlDecimal), 01/01/0001)] Не думаете ли вы, что это само по себе вызовет ошибку при попытке преобразовать возможное значение datetime в тип SQLDecimal? - person keepsmilinyaar; 06.01.2010
comment
Упс. :) Спасибо - это осталось от теста DateTime. Изменено на -1. - person Randy supports Monica; 06.01.2010
comment
{Недопустимое преобразование из «System.String» в «System.Data.SqlTypes.SqlDecimal».} - это то, что я получаю, когда вставляю строку, упомянутую вами. [FieldNullValue(typeof(SqlDecimal), -1)] Любые другие идеи??? - person keepsmilinyaar; 06.01.2010

Я никогда не работал с FileHelpers, но вместо этого вы можете попробовать:

[FileHelpers.FieldNullValue(null)]
public SqlDecimal? Rate;

В дополнение к другим вашим качествам, конечно.

Обратите внимание на большое изменение: я добавил вопросительный знак к SqlDecimal, чтобы сделать его обнуляемым тип.

Затем вы можете использовать Rate.HasValue, чтобы определить, является ли оно нулевым или нет, и Rate.Value, чтобы получить доступ к SqlDecimal, если HasValue верно.

Что-то вроде этого будет правильно использовать SqlDecimal.Null после того, как вы проанализируете файл:

SqlDecimal trueRate = (Rate.HasValue ? Rate.Value : SqlDecimal.Null);

Изменить. Возможно, если вы сделаете Rate обнуляемым (SqlDecimal?), вам даже не понадобится атрибут «FieldNullValue». Опять же, я не знаком с библиотекой. :(

person Sapph    schedule 06.01.2010
comment
Нет, он упомянул, что пробовал SqlDecimal.Null, который не является постоянным выражением. - person Sapph; 06.01.2010
comment
@Sapph: извините, мой плохой - я недостаточно внимательно прочитал вопрос (и ваш ответ). - person marc_s; 06.01.2010

Почему вы не можете использовать Decimal или подходящий тип данных .net вместо SqlDecimal?
Я предлагаю вместо этого изменить код на public Decimal? Rate;.

person shahkalpeshp    schedule 06.01.2010
comment
Не совсем уверен, как работают FileHelpers. Вероятно, придется попробовать и взглянуть на исходный код. Я действительно хочу преобразовать весь файл csv в datatable, чтобы я мог SQLBulkCopy сохранять данные. Но я получаю следующую ошибку: при использовании типов, допускающих значение NULL, DataSet не поддерживает System.Nullable‹› Кроме того, при вызове fileHelperEngine.ReadFileAsDT() метод переопределения FieldToString() не запускается. - person keepsmilinyaar; 11.01.2010