Comparar datatable con dbnull

Primero que nada le envío un cordial saludo esperando y deseando se encuentre con bien
en esta ocasión acudo a ud con una duda la cual ha salido de mi alcance y consiste en lo siguiente: estoy realizando una página web en la cual hago diversas consultas a una base de datos bueno pero existe una en especifico la cual en diversas ocasiones se encontraran valores nulos para lo cual como lo estoy almacenando en una datatable me muestra el error de que no se pueden asignar valores nulos como es de esperar he intentado varias formas de controlarlo sin existo no se si exista una forma para realizar este proceso todo esto con c#
if (Meses == DBNull.Value)
..........
o if (Meses ==null)
...
Pero no se donde o como lo pueda comparar para saber si no existe valores en esa consulta que se retorna
por que en si solo hago una consulta en la cual sumo los datos de los meses en un determinado año pero en ocasiones esos datos no existen y me retorna la tabla en nulo ¿cómo puedo controlar esta excepción?
Respuesta
1
*****************************************************
Pues mira si el datatable quieres controlar en caso de que no tenga ningún valor lo puedes hacer con esto, esto de los rows. Count te controla si tienen o no datos el datatable, digamos que el datatable es ese de el que tu obtienes ok
DataTable d = new DataTable();
            d.Rows.Count
*****************************************************
Si deseas controlar registro por registro, al momento de recorrerte el datatable registro por registro, debes hacer una validación de que si el valor de cierto campo es nulo por defecto le mando algún valor como 0 o string. Empty
con ese te deberia servir normalmente pero ese es solo para datos no para toda la fila
dato == System.DBNull.Value
Te pongo un peque ejemplo de como utilizo yo, por cierto te recomiendo que al datatable lo combiertas a datareader bueno yo solo tengo código con data reader pero es casi lo mismo ahí te pongo el código a que lo mires
DataTable d = new DataTable();
            while (d.CreateDataReader().Read())
            {
                string cedula = string.Empty;
                try
                {
                    cedula = (string)ConvertirAlTipoDeDato(returnData["CEDULA"], returnData["CEDULA"].GetType(), System.TypeCode.String);
                }
                catch(Exception)
                {
                    cedula = "1111111111";
                }
            }
Esta es la funcion que convierte los tipos de datos ConvertirAlTipoDeDato
private object ConvertirAlTipoDeDato(object dato, Type tipo, TypeCode codigoTipo)
        {
            CultureInfo cultureInfo = new CultureInfo("es-EC", true);
            if (codigoTipo == TypeCode.Decimal)
            {
                if (dato == System.DBNull.Value) return Convert.ToDecimal(1);
                switch (System.Type.GetTypeCode(tipo))
                {
                    case TypeCode.Decimal:
                        return (decimal)dato;
                    case TypeCode.Byte:
                    case TypeCode.Int16:
                    case TypeCode.Int32:
                    case TypeCode.Double:
                        return (decimal)Convert.ToDecimal(dato);
                    case TypeCode.String:
                        decimal resultado;
                        decimal.TryParse((string)dato, out resultado);
                        return resultado;
                }
            }
            if (codigoTipo == TypeCode.Int32)
            {
                if (dato == System.DBNull.Value) return Convert.ToInt32(1);
                switch (System.Type.GetTypeCode(tipo))
                {
                    case TypeCode.Byte:
                        return (Int32)Convert.ToInt32(dato);
                    case TypeCode.Decimal:
                        return (Int32)Convert.ToInt32(dato);
                    case TypeCode.Int16:
                        return (Int32)Convert.ToInt32(dato);
                    case TypeCode.Double:
                        return (Int32)Convert.ToInt32(dato);
                    case TypeCode.Int32:
                        return (Int32)dato;
                    case TypeCode.String:
                        int resultado;
                        Int32.TryParse((string)dato, out resultado);
                        return resultado;
                }
            }
            if (codigoTipo == TypeCode.DateTime)
            {
                if (dato == System.DBNull.Value) return System.DateTime.Now.ToShortDateString();
                switch (System.Type.GetTypeCode(tipo))
                {
                    case TypeCode.String:
                        string fecha = (string)dato;
                        //fecha = fecha.Substring(0, 2) + "/" + fecha.Substring(2, 2) + "/" + fecha.Substring(4, 4);
                        DateTime resultado;
                        DateTime.TryParse((string)fecha, out resultado);
                        return resultado;
                    case TypeCode.DateTime:
                        return dato;
                }
            }
            if (codigoTipo == TypeCode.String)
            {
                if (dato == System.DBNull.Value) return "ND";
                switch (System.Type.GetTypeCode(tipo))
                {
                    case TypeCode.Byte:
                    case TypeCode.SByte:
                    case TypeCode.Int16:
                    case TypeCode.Int32:
                        return (string)dato.ToString();
                    case TypeCode.Decimal:
                        decimal valor = (decimal)dato;
                        return (string)valor.ToString("", cultureInfo);
                    case TypeCode.String:
                        return (string)dato;
                }
            }
            if (dato == System.DBNull.Value) return 0;
            return null;
        }
*****************************************************
tambien puedes controlar con
try
{
//lineas de codigo en caso normal
}Catch(Exception)
{
//en caso de error hacer esto
}
*****************************************************
Jaja disculparas el testamento saludos
Muy bien chequearé el código pero por lo mientras te mando el mio para ver si desde ahí se puede arreglar y no tener que modificar más
aquí hago llamado al procedimiento
DataTable Meses = WB.LlenaMeses(int.Parse(txtaño.Text));
y aqui uso el valor del datetable
if (Convert.ToInt32(Meses.Rows[0][0]) == 0 | Meses.Rows[0][0] == null)
            ddlmes.Items.Add("Enero");
Pero como no hay datos me marca este error ***"No se puede convertir un objeto DBNull en otros tipos."
este es el procedimiento donde hago la consulta
public DataTable LlenaMeses(int año)
        {
            DataTable dt = new DataTable();
            DataSet ds = new DataSet();
            cn.Open();
            string consulta = "select Sum(Enero), Sum(Febrero), Sum(Marzo), Sum(Abril), Sum(Mayo), Sum(Junio), Sum(Julio)," +
                "Sum(Agosto), Sum(Septiembre), Sum(Octubre), Sum(Noviembre), Sum(Diciembre) from tbl_cientifica_A where año=" + "'" + año + "'";
            SqlDataAdapter da = new SqlDataAdapter(consulta, cn);
            da.Fill(ds, "MesesVacios");
            dt = ds.Tables["MesesVacios"];
            cn.Close();
            return dt;
        }
Pero donde no siempre tiene datos o más bien no existen
y ya probé la solución mencionada anterior le agradezco por ella pero el problema es que cuando se realiza la consulta que solo hace la suma de registros entonces me regresa siempre una columna ya sea con datos o con valores nulos por lo tanto siempre se cumple la condición de
ds. Tables.Count>0
es ahí donde no se que hacer para determinar que es o no vacía y me arrojo valores nulos
Ahh veras si cierras la cneccion antes de regresar esa vaina del datatable sabe regresar nulos
Y puedes compararle con el ds.Tables["MesesVacios"] is empty o algo así, o rows también o count si es 0 para que no regrese nulos
Muy bien le agradezco mucho la ayuda y el interés ya me han respondido por otro lado pero no estaba muy perdido en cuanto a su respuesta de nuevo mil gracias

1 respuesta más de otro experto

Respuesta
1
Enviame un fragmento de código donde se esta cayendo tu lógica para echarle una revisada y poderte ayudar
Ok gracias bueno aquí hago llamado al procedimiento
?DataTable Meses = WB.LlenaMeses(int.Parse(txtaño.Text));
este es el procedimiento donde hago la consulta
public DataTable LlenaMeses(int año)
        {
            DataTable dt = new DataTable();
            DataSet ds = new DataSet();
            cn.Open();
            string consulta = "select Sum(Enero), Sum(Febrero), Sum(Marzo), Sum(Abril), Sum(Mayo), Sum(Junio), Sum(Julio)," +
                "Sum(Agosto), Sum(Septiembre), Sum(Octubre), Sum(Noviembre), Sum(Diciembre) from tbl_cientifica_A where año=" + "'" + año + "'";
            SqlDataAdapter da = new SqlDataAdapter(consulta, cn);
            da.Fill(ds, "MesesVacios");
            dt = ds.Tables["MesesVacios"];
            cn.Close();
            return dt;
        }
Pero donde no siempre tiene datos o más bien no existen
Bueno de lo que veo talvez donde se cuelga es en esta línea dt = ds.Tables["MesesVacios"];
lo que puedes hacer es primero verificar si la consulta arrojo algo, haciendo primero esta validacion
if(ds.Tables.Count > 0)
      dt = ds.Tables["MesesVacios"];
else
      dt = null;
Si no es ese el caso, dime exactamente en que línea se cuelga el programa y mandame el error exacto que te sale para poder ayudarte.
Ok entonces disculpa no me supe explicar bien
aquí hago llamado al procedimiento
DataTable Meses = WB.LlenaMeses(int.Parse(txtaño.Text));
y aqui uso el valor del datetable
if (Convert.ToInt32(Meses.Rows[0][0]) == 0 | Meses.Rows[0][0] == null)
            ddlmes.Items.Add("Enero");
Pero como no hay datos me marca este error ***"No se puede convertir un objeto DBNull en otros tipos."
este es el procedimiento donde hago la consulta
public DataTable LlenaMeses(int año)
        {
            DataTable dt = new DataTable();
            DataSet ds = new DataSet();
            cn.Open();
            string consulta = "select Sum(Enero), Sum(Febrero), Sum(Marzo), Sum(Abril), Sum(Mayo), Sum(Junio), Sum(Julio)," +
                "Sum(Agosto), Sum(Septiembre), Sum(Octubre), Sum(Noviembre), Sum(Diciembre) from tbl_cientifica_A where año=" + "'" + año + "'";
            SqlDataAdapter da = new SqlDataAdapter(consulta, cn);
            da.Fill(ds, "MesesVacios");
            dt = ds.Tables["MesesVacios"];
            cn.Close();
            return dt;
        }
Pero donde no siempre tiene datos o más bien no existen
y ya probé la solución mencionada anterior le agradezco por ella pero el problema es que cuando se realiza la consulta que solo hace la suma de registros entonces me regresa siempre una columna ya sea con datos o con valores nulos por lo tanto siempre se cumple la condición de
ds. Tables.Count>0
es ahí donde no se que hacer para determinar que es o no vacía y me arrojo valores nulos
Bueno te digo una solucion muy simple (no es la mas optima) ojala te sirva
string dato = Convert.ToInt32(Meses.Rows[0][0].toString();
try{
        int num = Convert.ToInt32(dato);
        if(num == 0)
             ddlmes.Items.Add("Enero");
} catch(Exception ex){
       //Aki el kodigo k kieres k se ejecute en caso el valor sea nulo, no exista o no sea un numero
}
SUERTE
if (Convert.ToInt32(Meses.Rows[0][0]) == 0 | Meses.Rows[0][0] == null)
            ddlmes.Items.Add("Enero");

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas