对象不能从dbnull转换为其他类型

xxslljrj  于 2021-06-15  发布在  Mysql
关注(0)|答案(7)|浏览(348)

对象不能从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;
    }
}
vx6bjr1n

vx6bjr1n1#

我认为您的输出参数返回了一个dbnull值。加一张这样的支票

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

z2acfund2#

我怀疑那条线

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
}
3df52oht

3df52oht3#

我今天遇到了这个问题,并通过检查mapping类解决了它。我有一个类,它有5个属性,存储过程返回的5列被Map到其中。这些属性是不可为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

希望这对别人有帮助。

dauxcl2d

dauxcl2d4#

处理这类事情时,tryparse通常是最优雅的方式:

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

x759pob25#

对于其他从google进入此页面的用户:
datarow还有一个函数 .IsNull("ColumnName") ```
public DateTime? TestDt;
public Parse(DataRow row)
{
if (!row.IsNull("TEST_DT"))
TestDt = Convert.ToDateTime(row["TEST_DT"]);
}

mwngjboj

mwngjboj6#

错误原因:在面向对象编程语言中,null表示缺少对对象的引用。dbnull表示未初始化的变量或不存在的数据库列。source: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。

vshtjzan

vshtjzan7#

你需要检查一下 DBNull ,不是 null . 另外,三个人中有两个 ReplaceNull 方法没有意义。 double 以及 DateTime 是不可为空的,所以检查它们 null 永远都是 false ...

相关问题