对象不能从DBNull转换为其他types
对象不能从DBNull转换为其他types。
我有一个以下的函数抛出上述错误。 我正在处理存储过程中的所有空值和C#代码。
那么它在哪里得到这个错误?
我可以看到catch块中的错误。 但是我不明白在下面的哪个行create()得到错误。
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; } }
我在想你的输出参数会返回一个DBNull值。 添加一个像这样的支票
var outputParam = dataAccCom.GetParameterValue(IDbCmd, "op_Id"); if(!(outputParam is DBNull)) DataTO.Id = Convert.ToInt64(outputParam);
我怀疑那一行
DataTO.Id = Convert.ToInt64(dataAccCom.GetParameterValue(IDbCmd, "op_Id"));
正在造成这个问题。 存储过程是否可能将op_Id
值设置为null?
为了防止它使用Convert.IsDBNull
方法。 例如:
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
,而不是null
。 另外,你的三个ReplaceNull
方法中有两个没有意义。 double
和DateTime
是不可空的,所以检查它们为null
将始终是false
…
TryParse通常是处理这种types的最优雅的方法:
long temp = 0; if (Int64.TryParse(dataAccCom.GetParameterValue(IDbCmd, "op_Id").ToString(), out temp)) { DataTO.Id = temp; }
错误原因:在面向对象的编程语言中,null表示没有对象的引用。 DBNull表示未初始化的变体或不存在的数据库列。 来源:MSDN
我遇到的实际代码错误:
在更改代码之前:
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; }
更改代码后:
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; }
结论:当数据库值返回空值时,我们推荐使用DBNull类,而不是像在C#语言中那样指定为null。
对于从Google上到达此页面的其他人:
DataRow也有一个函数.IsNull("ColumnName")
public DateTime? TestDt; public Parse(DataRow row) { if (!row.IsNull("TEST_DT")) TestDt = Convert.ToDateTime(row["TEST_DT"]); }