Estoy usando un SQLdatareader para construir POCO a partir de una base de datos. El código funciona excepto cuando encuentra un valor nulo en la base de datos. Por ejemplo, si la columna Nombre en la base de datos contiene un valor nulo, se genera una excepción.
employee.FirstName = sqlreader.GetString(indexFirstName);
¿Cuál es la mejor manera de manejar valores nulos en esta situación?
c#
sqldatareader
DenaliHardtail
fuente
fuente
int colIndex = reader.GetOrdinal(fieldname);
y sobrecargar fácilmente laSafeGetString
función de @ marc_s .Debe usar el
as
operador combinado con el??
operador para los valores predeterminados. Los tipos de valor deberán leerse como anulables y tener un valor predeterminado.El
as
operador maneja el casting, incluida la verificación de DBNull.fuente
sqlreader[indexAge] as string ?? ""
, siempre obtendrás""
. Considere si realmente quiere(int?)sqlreader[indexAge] ?? defaultValue
, así que si su SQL cambia, obtendrá excepciones en lugar de valores incorrectos. @ Stevo3000: el valor predeterminado (int) es 0, no -1. @ Chris: Asegúrate de estar usando el que realmente quieres.Para una cadena, simplemente puede convertir la versión del objeto (a la que se accede mediante el operador de matriz) y terminar con una cadena nula para nulos:
o
Para enteros, si convierte a un int que admite valores NULL, puede usar GetValueOrDefault ()
o el operador de fusión nula (
??
).fuente
null
sino un objeto DBNull. La diferencia entre las dos declaraciones es que la primera fallará si no es una cadena, mientras que la segunda simplemente devolverá nulo si no es una cadena.IsDbNull(int)
generalmente es mucho más lento que usar métodos comoGetSqlDateTime
y luego compararlosDBNull.Value
. Pruebe estos métodos de extensión paraSqlDataReader
.Úselos así:
fuente
Una forma de hacerlo es verificar los nulos db:
fuente
reader.IsDbNull(ColumnIndex)
funciona como muchas respuestas dice.Y quiero mencionar que si trabaja con nombres de columna, solo comparar tipos puede ser más cómodo.
fuente
No creo que haya un valor de columna NULL , cuando las filas se devuelven dentro de un lector de datos utilizando el nombre de la columna.
Si lo hace
datareader["columnName"].ToString();
, siempre le dará un valor que puede ser una cadena vacía (String.Empty
si necesita comparar).Usaría lo siguiente y no me preocuparía demasiado:
fuente
Esta solución depende menos del proveedor y funciona con un lector SQL, OleDB y MySQL:
fuente
Lo que tiendo a hacer es reemplazar los valores nulos en la instrucción SELECT con algo apropiado.
Aquí reemplazo cada nulo con una cadena en blanco. Su código no arrojará un error en ese caso.
fuente
Puede escribir una función genérica para verificar Nulo e incluir el valor predeterminado cuando es NULO. Llame a esto cuando lea Datareader
Al leer el uso del lector de datos
fuente
Verifique
sqlreader.IsDBNull(indexFirstName)
antes de intentar leerlo.fuente
Al influir en la respuesta de getpsyched , creé un método genérico que verifica el valor de la columna por su nombre
Uso:
fuente
cómo crear métodos auxiliares
Para cadena
Uso
Para int
Uso
Para la fecha
Uso
Nota: para DateTime declare varialbe como
fuente
Como una adición a la respuesta de marc_s, puede usar un método de extensión más genérico para obtener valores de SqlDataReader:
fuente
Creo que te gustaría usar:
fuente
Utilizamos una serie de métodos estáticos para extraer todos los valores de nuestros lectores de datos. Entonces, en este caso, estaríamos llamando.
DBUtils.GetString(sqlreader(indexFirstName))
El beneficio de crear métodos estáticos / compartidos es que no tiene que hacer las mismas verificaciones una y otra vez ...El (los) método (s) estático (s) contendría código para verificar nulos (ver otras respuestas en esta página).
fuente
Puede usar el operador condicional:
fuente
Aquí hay muchas respuestas con información útil (y alguna información incorrecta), me gustaría reunir todo.
La respuesta corta a la pregunta es verificar DBNull: casi todos están de acuerdo con este bit :)
En lugar de utilizar un método auxiliar para leer valores anulables por tipo de datos SQL, un método genérico nos permite abordar esto con mucho menos código. Sin embargo, no puede tener un único método genérico tanto para los tipos de valores anulables como para los tipos de referencia, ¿esto se discute extensamente en el tipo Nullable como un parámetro genérico posible? y restricción de tipo genérico C # para todo lo que se puede anular .
Entonces, siguiendo las respuestas de @ZXX y @getpsyched, terminamos con esto, 2 métodos para obtener valores anulables y he agregado un tercero para valores no nulos (completa el conjunto basado en el nombre del método).
Usualmente uso nombres de columna, modifíquelos si usa índices de columna. En base a estos nombres de métodos, puedo decir si espero que los datos sean anulables o no, bastante útil cuando se mira el código escrito hace mucho tiempo.
Consejos;
Por último, al probar los métodos anteriores en todos los tipos de datos de SQL Server descubrí que no puede obtener directamente un char [] de un SqlDataReader, si desea un char [] tendrá que obtener una cadena y usar ToCharArray ().
fuente
Estoy usando el código enumerado a continuación para manejar celdas nulas en una hoja de Excel que se lee en una tabla de datos.
fuente
fuente
y / o usar operador ternario con asignación:
reemplace el valor predeterminado (cuando sea nulo) según corresponda para cada tipo de propiedad ...
fuente
Este método depende de indexFirstName, que debería ser el ordinal de columna basado en cero.
Si no conoce el índice de la columna pero no desea verificar un nombre, puede usar este método de extensión:
Y usa el método de esta manera:
fuente
Antigua pregunta, pero tal vez alguien todavía necesita una respuesta
en realidad trabajé alrededor de este problema así
Para int:
lo mismo para la cadena solo devuelve "" en lugar de 0 ya que "" es una cadena vacía
para que puedas usarlo como
y
muy flexible para que pueda insertar cualquier consulta para leer cualquier columna y nunca volverá con error
fuente
Aquí hay una clase auxiliar que otros pueden usar si la necesitan según la respuesta de @marc_s:
fuente
Convierta las manijas DbNull con sensatez.
fuente
también puedes verificar esto
fuente
SqlDataReader