无法将对象从DBNull强制转换为其他类型。
我有以下函数抛出上述错误。我正在处理存储过程和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;
}
}
答案 0 :(得分:51)
我认为你的输出参数带有DBNull值。为此添加支票
var outputParam = dataAccCom.GetParameterValue(IDbCmd, "op_Id");
if(!(outputParam is DBNull))
DataTO.Id = Convert.ToInt64(outputParam);
答案 1 :(得分:14)
我怀疑该行
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
}
答案 2 :(得分:2)
您需要检查DBNull
,而不是null
。此外,您的三种ReplaceNull
方法中有两种没有意义。 double
和DateTime
不可为空,因此检查null
false
将始终为{{1}} ...
答案 3 :(得分:2)
错误原因:在面向对象的编程语言中,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;
}
结论:当数据库值返回null值时,我们建议使用DBNull类,而不是像C#语言一样指定为null。
答案 4 :(得分:1)
TryParse通常是处理此类事情的最优雅方式:
long temp = 0;
if (Int64.TryParse(dataAccCom.GetParameterValue(IDbCmd, "op_Id").ToString(), out temp))
{
DataTO.Id = temp;
}
答案 5 :(得分:0)
对于从google访问此页面的其他人:
DataRow还有一个函数.IsNull("ColumnName")
public DateTime? TestDt;
public Parse(DataRow row)
{
if (!row.IsNull("TEST_DT"))
TestDt = Convert.ToDateTime(row["TEST_DT"]);
}
答案 6 :(得分:0)
我今天遇到了这个问题,并通过检查映射类解决了它。我有一个具有5个属性的类,将从存储过程返回的5列映射到该属性。这些属性是不可为空的,由于这个原因,我遇到了错误。我将它们设置为可为空,问题得以解决。
public int? Pause { get; set; }
public int? Delay { get; set; }
public int? Transition { get; set; }
public int? TransitionTime { get; set; }
public int? TransitionResolution { get; set; }
添加了“?”数据类型使它们可以为空。
第二,我还在存储过程中添加了isNull检查,如下所示:
isnull(co_pivot.Pause, 0) as Pause,
isnull(co_pivot.Delay, 0) as Delay,
isnull(co_pivot.Transition, 0) as Transition,
isnull(co_pivot.TransitionTime, 0) as TransitionTime,
isnull(co_pivot.TransitionResolution, 0) as TransitionResolution
希望这对某人有帮助。