Разбор десятичного числа из DataReader - PullRequest
6 голосов
/ 01 сентября 2009

Я нашел обходной путь для этой ошибки, но теперь мне действительно любопытно, почему это происходит, и мне было интересно, если бы кто-то еще имел эту ошибку.

Моя функция выглядит следующим образом:

public void Blog_GetRating(int blogID, ref decimal rating, ref int voteCount)
{
    // Sql statements
    // Sql commands

    if (DataReader.Read())
    {
        // this line throws a 'Input string was not in a correct format.' error.
        rating = decimal.Parse(DataReader["Rating"].ToString());

        // this works absolutly fine?!
        decimal _rating = 0;
        decimal.TryParse(DataReader["Rating"].ToString(), out _rating);

        rating = _rating;
    }
}

Кто-нибудь когда-либо видел это раньше?

Что еще страннее, если я наберу это:

rating = decimal.Parse("4.0");

, который работает нормально, 4.0 - это то, что выходит из моего DataReader.

Как я уже говорил ранее, метод TryParse работает нормально, поэтому он не мешает мне нести, но теперь мне действительно интересно посмотреть, есть ли у кого-нибудь ответ на него.

С нетерпением жду некоторых ответов!

Sean

РЕДАКТИРОВАТЬ - РЕШЕНО

Метод decimal.Parse работал нормально, во второй раз, когда функция работала (была в цикле), сообщение не было оценено, поэтому считыватель данных возвращал нулевое значение. Обертывание COALESCE вокруг моего вычисления в SQL решило проблему отлично. Следовательно, как вы сказали, метод tryparse не генерирует исключение, а просто сохраняет значение по умолчанию от 0 до _rating.

Ответы [ 5 ]

11 голосов
/ 01 сентября 2009

Мне это не кажется странным.

Decimal.Parse() - это , предполагается для исключения из-за плохих форматов. Decimal.TryParse() не сгенерирует это исключение, а просто вернет false. Важно то, что вы не проверяете возвращаемое значение из Decimal.TryParse(). Я дам вам очень хорошие шансы, что Decimal.TryParse() вернет false для каждого входа, который вызывает исключение с Decimal.Parse(), и правда везде И когда Decimal.TryParse() возвращает false, выходной аргумент всегда равен просто «0».

Единственное возможное предостережение - локализация. Если Decimal.Parse() жалуется на кажущийся нормальным ввод, вы можете проверить, использует ли числовой формат (текущая культура), используемый на вашем сервере, запятую, а не десятичную дробь, чтобы отделить коэффициент от мантиссы. Но, учитывая, что ваш тест "4.0" работал нормально, я сомневаюсь, что это проблема.

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

2 голосов
/ 01 сентября 2009

Вы говорите это:

    // this works absolutly fine?!
    decimal _rating = 0;
    decimal.TryParse(DataReader["Rating"].ToString(), out _rating);

Но вы на самом деле не проверяли возвращаемое значение TryParse. Я полагаю, что ваш TryParse фактически не работает (возвращает false), поскольку decimal.Parse и decimal.TryParse используют одни и те же «правила» для синтаксического анализа, учитывая используемые вами перегрузки.

Я подозреваю, что ни один из них не работает так, как вы думаете. Возможно, оба сбоя, но TryParse не сработает.

1 голос
/ 26 сентября 2014

У меня сегодня такая же проблема. Попробуйте это:

rating = decimal.Parse("4,0");

Это даст вам ту же ошибку.


Причиной этого является культура. Во французской культуре 4.0 представлен как 4,0, и, следовательно, он создает исключение.

decimal.TryParse - это метод, инвариантный к культуре, и, следовательно, он отлично работает.

1 голос
/ 01 июня 2012

Десятичный столбец sql не будет анализировать строку, которая может быть преобразована в десятичную, поэтому tryparse вернет false. Попробуйте что-то вроде этого:

 if (Convert.IsDBNull(reader["DecimalColumn"]))
     {
        decimalData = 0m;
     }
     else
     {
        decimalData = reader.GetDecimal(reader.GetOrdinal("DecimalColumn"));
     }
0 голосов
/ 01 сентября 2009

Измените свой TryParse на это и попробуйте снова:

if (!decimal.TryParse(DataReader["Rating"].ToString(), out _rating))
{
  throw new Exception("Input string was not in a correct format");
}

Бьюсь об заклад, это бросает ...

...