verificar valores valor validar vacio tener seleccionar reemplazar que por objeto nulo not net ejemplos ejemplo debe como campos campo acepta c# sqldatareader

c# - validar - Lector de datos SQL: manejo de valores de columna nulos



validar null en c# (22)

Estoy usando un SQLdatareader para construir POCO desde 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 lanza una excepción.

employee.FirstName = sqlreader.GetString(indexFirstName);

¿Cuál es la mejor manera de manejar valores nulos en esta situación?


Alguna vez puedes comprobar esto también

if(null !=x && x.HasRows) { ....}


Cómo crear métodos de ayuda.

Para la cuerda

private static string MyStringConverter(object o) { if (o == DBNull.Value || o == null) return ""; return o.ToString(); }

Uso

MyStringConverter(read["indexStringValue"])

Para int

private static int MyIntonverter(object o) { if (o == DBNull.Value || o == null) return 0; return Convert.ToInt32(o); }

Uso

MyIntonverter(read["indexIntValue"])

Para la fecha

private static DateTime? MyDateConverter(object o) { return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o); }

Uso

MyDateConverter(read["indexDateValue"])

Nota: para DateTime declarar varialbe como

DateTime? variable;


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 del SqlDataReader:

public static T SafeGet<T>(this SqlDataReader reader, int col) { return reader.IsDBNull(col) ? default(T) : reader.GetFieldValue<T>(col); }


Compruebe sqlreader.IsDBNull(indexFirstName) antes de intentar leerlo.


Creo que querrías usar:

SqlReader.IsDBNull(indexFirstName)


Deberías usar el operador as combinado con el ?? Operador para los valores por defecto. Los tipos de valor deberán leerse como anulables y se les dará un valor predeterminado.

employee.FirstName = sqlreader[indexFirstName] as string; employee.Age = sqlreader[indexAge] as int? ?? default(int);

El operador as encarga de la fundición, incluida la comprobación de DBNull.


Esta solución depende menos del proveedor y funciona con un SQL, OleDB y MySQL Reader:

public static string GetStringSafe(this IDataReader reader, int colIndex) { return GetStringSafe(reader, colIndex, string.Empty); } public static string GetStringSafe(this IDataReader reader, int colIndex, string defaultValue) { if (!reader.IsDBNull(colIndex)) return reader.GetString(colIndex); else return defaultValue; } public static string GetStringSafe(this IDataReader reader, string indexName) { return GetStringSafe(reader, reader.GetOrdinal(indexName)); } public static string GetStringSafe(this IDataReader reader, string indexName, string defaultValue) { return GetStringSafe(reader, reader.GetOrdinal(indexName), defaultValue); }


Este método depende de indexFirstName, que debería ser el ordinal de la columna de base cero.

if(!sqlReader.IsDBNull(indexFirstName)) { employee.FirstName = sqlreader.GetString(indexFirstName); }

Si no conoce el índice de la columna pero no desea verificar un nombre, puede usar este método de extensión en su lugar:

public static class DataRecordExtensions { public static bool HasColumn(this IDataRecord dr, string columnName) { for (int i=0; i < dr.FieldCount; i++) { if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase)) return true; } return false; } }

Y usa el método así:

if(sqlReader.HasColumn("FirstName")) { employee.FirstName = sqlreader["FirstName"]; }


Estoy utilizando el código que se indica a continuación para manejar celdas nulas en una hoja de Excel que se lee en una tabla de datos.

if (!reader.IsDBNull(2)) { row["Oracle"] = (string)reader[2]; }


Lo que tiendo a hacer es reemplazar los valores nulos en la instrucción SELECT con algo apropiado.

SELECT ISNULL(firstname, '''') FROM people

Aquí sustituyo cada nulo con una cadena en blanco. Su código no tirará por error en ese caso.


Necesitas verificar el IsDBNull :

if(!SqlReader.IsDBNull(indexFirstName)) { employee.FirstName = sqlreader.GetString(indexFirstName); }

Esa es la única forma confiable de detectar y manejar esta situación.

Envolví esas cosas en métodos de extensión y tiendo a devolver un valor predeterminado si la columna es null :

public static string SafeGetString(this SqlDataReader reader, int colIndex) { if(!reader.IsDBNull(colIndex)) return reader.GetString(colIndex); return string.Empty; }

Ahora puedes llamarlo así:

employee.FirstName = SqlReader.SafeGetString(indexFirstName);

y nunca más tendrá que preocuparse por una excepción o un valor null .


No creo que haya un valor de columna NULL , cuando las filas se devuelven dentro de un datareader usando el nombre de 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:

employee.FirstName = sqlreader["columnNameForFirstName"].ToString();


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:

employee.FirstName = (string)sqlreader[indexFirstName];

o

employee.FirstName = sqlreader[indexFirstName] as string;

Para los enteros, si convierte a un int anulable, puede usar GetValueOrDefault ()

employee.Age = (sqlreader[indexAge] as int?).GetValueOrDefault();

o el operador de unión nula ( ?? ).

employee.Age = (sqlreader[indexAge] as int?) ?? 0;


Pregunta antigua, pero tal vez alguien todavía necesita una respuesta.

En realidad trabajé en torno a este problema así

Para int:

public static object GatDataInt(string Query, string Column) { SqlConnection DBConn = new SqlConnection(ConnectionString); if (DBConn.State == ConnectionState.Closed) DBConn.Open(); SqlCommand CMD = new SqlCommand(Query, DBConn); SqlDataReader RDR = CMD.ExecuteReader(); if (RDR.Read()) { var Result = RDR[Column]; RDR.Close(); DBConn.Close(); return Result; } return 0; }

lo mismo para la cadena solo devuelve "" en lugar de 0 ya que "" es una cadena vacía

para que puedas usarlo como

int TotalPoints = GatDataInt(QueryToGetTotalPoints, TotalPointColumn) as int?;

y

string Email = GatDatastring(QueryToGetEmail, EmailColumn) as string;

muy flexible para que pueda insertar cualquier consulta para leer cualquier columna y nunca volverá con un error


Puede escribir una función genérica para verificar Nulo e incluir el valor predeterminado cuando es NULL. Llama a esto al leer Datareader

public T CheckNull<T>(object obj) { return (obj == DBNull.Value ? default(T) : (T)obj); }

Al leer el uso de Datareader

while (dr.Read()) { tblBPN_InTrRecon Bpn = new tblBPN_InTrRecon(); Bpn.BPN_Date = CheckNull<DateTime?>(dr["BPN_Date"]); Bpn.Cust_Backorder_Qty = CheckNull<int?>(dr["Cust_Backorder_Qty"]); Bpn.Cust_Min = CheckNull<int?>(dr["Cust_Min"]); }


Puede utilizar el operador condicional:

employee.FirstName = sqlreader["indexFirstName"] != DBNull.Value ? sqlreader[indexFirstName].ToString() : "";


Una forma de hacerlo es verificar los nulos de db:

employee.FirstName = (sqlreader.IsDBNull(indexFirstName) ? "" : sqlreader.GetString(indexFirstName));


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 a DBUtils.GetString(sqlreader(indexFirstName)) El beneficio de crear métodos estáticos / compartidos es que no tienes que hacer las mismas comprobaciones una y otra vez ...

El método (s) estático (s) contendría código para verificar si hay nulos (vea otras respuestas en esta página).


y / o usar operador ternario con asignación:

employee.FirstName = rdr.IsDBNull(indexFirstName))? String.Empty: rdr.GetString(indexFirstName);

reemplace el valor predeterminado (cuando sea nulo) según corresponda para cada tipo de propiedad ...


IsDbNull(int) suele ser mucho más lento que usar métodos como GetSqlDateTime y luego compararlo con DBNull.Value . Pruebe estos métodos de extensión para SqlDataReader .

public static T Def<T>(this SqlDataReader r, int ord) { var t = r.GetSqlValue(ord); if (t == DBNull.Value) return default(T); return ((INullable)t).IsNull ? default(T) : (T)t; } public static T? Val<T>(this SqlDataReader r, int ord) where T:struct { var t = r.GetSqlValue(ord); if (t == DBNull.Value) return null; return ((INullable)t).IsNull ? (T?)null : (T)t; } public static T Ref<T>(this SqlDataReader r, int ord) where T : class { var t = r.GetSqlValue(ord); if (t == DBNull.Value) return null; return ((INullable)t).IsNull ? null : (T)t; }

Úsalos así:

var dd = r.Val<DateTime>(ords[4]); var ii = r.Def<int>(ords[0]); int nn = r.Def<int>(ords[0]);


reader.IsDbNull(ColumnIndex) funciona como dicen muchas respuestas.

Y quiero mencionar que si trabaja con nombres de columna, la comparación de tipos puede ser más cómoda.

if(reader["TeacherImage"].GetType() == typeof(DBNull)) { //logic }


private static void Render(IList<ListData> list, IDataReader reader) { while (reader.Read()) { listData.DownUrl = (reader.GetSchemaTable().Columns["DownUrl"] != null) ? Convert.ToString(reader["DownUrl"]) : null; //没有这一列时,让其等于null list.Add(listData); } reader.Close(); }