El objeto no se puede convertir de DBNull a otros tipos

El objeto no se puede convertir de DBNull a otros tipos.

Tengo una función siguiente que arroja el error anterior. Estoy manejando todos los nulos en el procedimiento de la tienda y en el código de C #.

Entonces, ¿dónde está recibiendo este error?

Puedo ver el error en el bloque catch. Pero no entiendo qué línea en el siguiente create () obtiene el error.

public Boolean Create(DataTO DataTO) { IDbTrans transaction = null; IDbCmd IDbCmd; string EncryptedPassword = Encrypt(DataTO.txtPwd); Base dataAccCom = null; try { dataAccCom = Factory.Create(); dataAccCom.OpenConnection(); transaction = dataAccCom.BeginTransaction(); IDbCmd = dataAccCom.CreateCommand("sp_Register", true); dataAccCom.AddParameter(IDbCmd, "op_Id", DbType.Int64, 0, ParameterDirection.Output); dataAccCom.AddParameter(IDbCmd, "p_dlstTitle", DbType.String, ReplaceNull(DataTO.dlstTitle)); dataAccCom.AddParameter(IDbCmd, "p_txtFirstName", DbType.String, ReplaceNull(DataTO.txtFirstName)); dataAccCom.AddParameter(IDbCmd, "p_txtMiddleName", DbType.String, ReplaceNull(DataTO.txtMiddleName)); dataAccCom.AddParameter(IDbCmd, "p_txtLastName", DbType.String, ReplaceNull(DataTO.txtLastName)); dataAccCom.AddParameter(IDbCmd, "p_txtDob", DbType.DateTime, DataTO.txtDob); dataAccCom.AddParameter(IDbCmd, "p_txtDesig", DbType.String, ReplaceNull(DataTO.txtDesig)); dataAccCom.AddParameter(IDbCmd, "p_txtOFlatNo", DbType.String, ReplaceNull(DataTO.txtOFlatNo)); dataAccCom.AddParameter(IDbCmd, "p_txtOBuild", DbType.String, ReplaceNull(DataTO.txtOBuild)); dataAccCom.AddParameter(IDbCmd, "p_txtOPost", DbType.String, ReplaceNull(DataTO.txtOPost)); dataAccCom.AddParameter(IDbCmd, "p_txtOArea", DbType.String, ReplaceNull(DataTO.txtOArea)); dataAccCom.AddParameter(IDbCmd, "p_txtOCity", DbType.String, ReplaceNull(DataTO.txtOCity)); dataAccCom.AddParameter(IDbCmd, "p_txtRBuild", DbType.String, ReplaceNull(DataTO.txtRBuild)); dataAccCom.AddParameter(IDbCmd, "p_txtRPost", DbType.String, ReplaceNull(DataTO.txtRPost)); dataAccCom.AddParameter(IDbCmd, "p_txtUserID", DbType.String,ReplaceNull(DataTO.txtUserID)); dataAccCom.AddParameter(IDbCmd, "p_txtPwd", DbType.String, ReplaceNull(EncryptedPassword)); dataAccCom.ExecuteNonQuery(IDbCmd); DataTO.Id = Convert.ToInt64(dataAccCom.GetParameterValue(IDbCmd, "op_Id")); transaction.Commit(); return true; } catch (System.Exception ex) { if (transaction != null) { transaction.Rollback(); } throw ex; } finally { transaction = null; if (dataAccCom != null) { dataAccCom.CloseConnection(); } dataAccCom = null; IDbCmd = null; } } public string ReplaceNull(string value) { if (value == null) { return ""; } else { return value; } } public DateTime ReplaceNull(DateTime value) { if (value == null) { return DateTime.Now; } else { return value; } } public double ReplaceNull(double value) { if (value == null) { return 0.0; } else { return value; } } 

Estoy pensando que su parámetro de salida regresa con un valor DBNull. Agregue un cheque para eso como este

 var outputParam = dataAccCom.GetParameterValue(IDbCmd, "op_Id"); if(!(outputParam is DBNull)) DataTO.Id = Convert.ToInt64(outputParam); 

Sospecho que la línea

 DataTO.Id = Convert.ToInt64(dataAccCom.GetParameterValue(IDbCmd, "op_Id")); 

está causando el problema ¿Es posible que el valor op_Id esté establecido en nulo por el procedimiento almacenado?

Para Convert.IsDBNull ella, use el método Convert.IsDBNull . Por ejemplo:

 if (!Convert.IsDBNull(dataAccCom.GetParameterValue(IDbCmd, "op_Id")) { DataTO.Id = Convert.ToInt64(dataAccCom.GetParameterValue(IDbCmd, "op_Id")); } else { DataTO.Id = ...some default value or perform some error case management } 

DBNull comprobar DBNull , no null . Además, dos de tus tres métodos ReplaceNull no tienen sentido. double y DateTime no aceptan null , por lo que comprobar que no tengan null siempre será false

Motivo del error: en un lenguaje de progtwigción orientado a objetos, null significa la ausencia de una referencia a un objeto. DBNull representa una variante no inicializada o una columna de base de datos inexistente. Fuente: MSDN

Código actual que enfrenté error:

Antes cambió el código:

  if( ds.Tables[0].Rows[0][0] == null ) // Which is not working { seqno = 1; } else { seqno = Convert.ToInt16(ds.Tables[0].Rows[0][0]) + 1; } 

Después de cambiar el código:

  if( ds.Tables[0].Rows[0][0] == DBNull.Value ) //which is working properly { seqno = 1; } else { seqno = Convert.ToInt16(ds.Tables[0].Rows[0][0]) + 1; } 

Conclusión: cuando el valor de la base de datos devuelve el valor nulo, recomendamos utilizar la clase DBNull en lugar de simplemente especificar como un valor nulo en el lenguaje C #.

TryParse suele ser la manera más elegante de manejar este tipo de cosas:

 long temp = 0; if (Int64.TryParse(dataAccCom.GetParameterValue(IDbCmd, "op_Id").ToString(), out temp)) { DataTO.Id = temp; } 

Para otros que llegan a esta página desde google:

DataRow también tiene una función .IsNull("ColumnName")

  public DateTime? TestDt; public Parse(DataRow row) { if (!row.IsNull("TEST_DT")) TestDt = Convert.ToDateTime(row["TEST_DT"]); }