2009-09-01 21 views
5

He encontrado una solución para este error, pero ahora tengo mucha curiosidad de por qué esto estaría sucediendo, me preguntaba si alguien más ha tenido este error.Analizando un decimal de un DataReader

Mi función es la siguiente:

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; 
    } 
} 

Cualquiera que he visto eso antes?

Lo que es aún más extraño es que si escribo esto:

rating = decimal.Parse("4.0"); 

que funciona bien, el 4.0 es lo que está saliendo de mi DataReader.

Como dije anteriormente, el método TryParse funciona bien, así que no me detiene, pero ahora estoy realmente interesado en ver si alguien tiene una respuesta para ello.

¡Esperamos algunas respuestas!

Sean

EDITAR - RESOLVER

El método decimal.Parse estaba trabajando bien, la segunda vez que la función se ejecuta (estaba en un bucle), un puesto que no había sido calificado por lo que una valor nulo fue devuelto por el lector de datos. Envolver COALESCE en mi cálculo en SQL resolvió bien el problema. De ahí que, como dijiste, el método tryparse no lanzara una excepción, simplemente manteniendo el valor predeterminado de 0 en _rating.

+1

¿Por qué la columna no es numérica, por lo que no es necesario analizar? –

Respuesta

10

Eso no me parece extraño en absoluto.

Decimal.Parse() es supuso para lanzar una excepción para los formatos incorrectos. Decimal.TryParse() no arrojará esa excepción, sino que simplemente devuelve falso. El truco es que no está verificando el valor de retorno de Decimal.TryParse(). Te daré buenas probabilidades de que Decimal.TryParse() devuelva falso para cada entrada que causa una excepción con Decimal.Parse(), y verdadero en todos los demás. Y cuando Decimal.TryParse() devuelve falso, el argumento de salida siempre es solo "0".

La única advertencia posible es la localización. Si Decimal.Parse() se queja de una entrada aparentemente normal, puede verificar si el formato de número (cultura actual) utilizado en su servidor usa una coma en lugar de un decimal para separar el coeficiente de la mantisa. Pero dado que tu prueba "4.0" funcionó bien, dudo que este sea el problema.

Finalmente, al hacer esta conversión del lector de datos, debe considerar el tipo de columna fuente del lector de datos. Si ya puede ser un decimal. ¿Por qué convertirlo a una cadena solo para convertirlo nuevamente?

2

que está diciendo esto:

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

Pero en realidad no comprobar el valor de retorno de TryParse. Supongo que su TryParse está fallando (devolviendo false), ya que decimal.Parse y decimal.TryParse usan las mismas "reglas" para el análisis, debido a las sobrecargas que está utilizando.

Sospecho que ninguno de los dos funciona como usted piensa. Ambos probablemente estén fallando, pero TryParse no lanzará.

0

Cambiar la TryParse a esto y vuelve a intentarlo:

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

apuesto a esto tirar ...

1

La columna sql decimal no analizará en una cadena que puede convertir a un decimal, por lo que tryparse devolverá falso. Pruebe algo como esto:

if (Convert.IsDBNull(reader["DecimalColumn"])) 
    { 
     decimalData = 0m; 
    } 
    else 
    { 
     decimalData = reader.GetDecimal(reader.GetOrdinal("DecimalColumn")); 
    } 
+0

Gracias, esto fue útil cuando cambié de cargar un conjunto de datos (que estaba recibiendo la excepción OutOfMemory) a usar un DataReader. Lo hice como: 'decimalData = (Convert.IsDBNull (reader [" DecimalColumn "]))? 0: reader.GetDecimal (reader.GetOrdinal ("DecimalColumn")); ' – ScottK

1

Hoy me enfrenta el mismo problema. Prueba esto:

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

Se le dará el mismo error.


La razón de esto es la cultura. En la cultura francesa, 4.0 se representa como 4,0 y, por lo tanto, arroja una excepción.

decimal.TryParse es el método invariante de cultura y por lo tanto funciona bien usted.

+0

' decimal.TryParse ("4.0", NumberStyles.Number, CultureInfo.InvariantCulture, calificación de salida); ' –