C# 对象不能从DBNull强制转换为其他类型
对象不能从DBNull强制转换为其他类型 我有一个抛出上述错误的函数。我正在处理存储过程和C#代码中的所有空值 那么它从哪里得到这个错误呢 我可以在catch块中看到错误。但是我不明白下面create()中的哪一行出现了错误C# 对象不能从DBNull强制转换为其他类型,c#,.net,asp.net,parameters,C#,.net,Asp.net,Parameters,对象不能从DBNull强制转换为其他类型 我有一个抛出上述错误的函数。我正在处理存储过程和C#代码中的所有空值 那么它从哪里得到这个错误呢 我可以在catch块中看到错误。但是我不明白下面create()中的哪一行出现了错误 public Boolean Create(DataTO DataTO) { IDbTrans transaction = null; IDbCmd IDbCmd; string EncryptedPassword = Encrypt(DataTO
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通常是处理这类事情的最优雅的方法:
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;
}
更改代码后:
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#language那样仅指定为null。对于从google到达此页面的其他人: DataRow还有一个函数
.IsNull(“ColumnName”)
我今天遇到了这个问题,并通过检查mapping类解决了它。我有一个类,它有5个属性,存储过程返回的5列映射到该类。这些属性不可为null,因此我得到了错误。我使它们可以为空,问题就解决了
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
希望这对其他人有所帮助。请注意,
double
和DateTime
上的ReplaceNull
重载毫无价值。这些类型的值永远不能为null,因此永远不会通过if(value==null)
条件。当然,除非它们被设置为可为null,但这是另一种情况。您已经完成了该方法吗?在VisualStudio中,考虑中断所有异常(CTRL+ALT+E),并查看实际导致问题的线路。哇,哇!不要“扔前任”,只要“扔”,否则你会失去一些线索。这并不能解决你的问题,但养成这样做的习惯是一种很好的做法。^^我总是在学习新的东西。就在我认为我知道我需要知道的关于异常的信息的时候…也许更好一些Convert.IsDBNull()
?我的查询中有多个整数值。我能不能缩短这个过程,或者我必须为每个人都这样做?@Alexander,我希望你能在这之前找到答案,但是如果比这个短,可能会变得很难看,但是使用s三元可以工作:DataTO.Id=dataAccCom.GetParameterValue(IDbCmd,“op_Id”)==DBNull.Value?null:Convert.ToInt64(dataAccCom.GetParameterValue(IDbCmd,“op_Id”);