L’object non può essere lanciato da DBNull ad altri tipi

L’object non può essere lanciato da DBNull ad altri tipi.

Ho una funzione seguente che genera l’errore precedente. Sto gestendo tutti i null nella procedura di archiviazione e nel codice C #.

Allora, dove sta ottenendo questo errore?

Posso vedere l’errore nel blocco catch. Ma non sto capendo quale riga nel seguente create () ottiene l’errore.

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

Sto pensando che il tuo parametro di output ritorni con un valore DBNull. Aggiungi un assegno per questo come questo

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

Sospetto che la linea

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

sta causando il problema. È ansible che il valore op_Id sia impostato su null dalla stored procedure?

Per Convert.IsDBNull usa il metodo Convert.IsDBNull . Per esempio:

 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 } 

Devi controllare DBNull , non null . Inoltre, due dei tre metodi ReplaceNull non hanno senso. double e DateTime non sono annullabili, quindi controllarli per null sarà sempre false

Motivo dell’errore: in un linguaggio di programmazione orientato agli oggetti, null indica l’assenza di un riferimento a un object. DBNull rappresenta una variante non inizializzata o una colonna di database inesistente. Fonte: MSDN

Codice effettivo che ho affrontato errore:

Prima di cambiare il codice:

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

Dopo aver cambiato il codice:

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

Conclusione: quando il valore del database restituisce il valore nullo, si consiglia di utilizzare la class DBNull invece di specificare semplicemente null come nel linguaggio C #.

TryParse è in genere il modo più elegante per gestire questo tipo di cose:

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

Per gli altri che arrivano su questa pagina da google:

DataRow ha anche una funzione. .IsNull("ColumnName")

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