Объект не может быть приведен из DBNull к другим типам - PullRequest
34 голосов
/ 23 мая 2011

Объект не может быть приведен из 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;
    }
}

Ответы [ 7 ]

52 голосов
/ 23 мая 2011

Я думаю, что ваш выходной параметр возвращается со значением DBNull. Добавьте проверку для этого как это

var outputParam = dataAccCom.GetParameterValue(IDbCmd, "op_Id");
if(!(outputParam is DBNull))
     DataTO.Id = Convert.ToInt64(outputParam);
15 голосов
/ 23 мая 2011

Я подозреваю, что линия

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

вызывает проблему. Возможно ли, что значение op_Id устанавливается нулевым с помощью хранимой процедуры?

Чтобы защититься от него, используйте метод 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 голосов
/ 07 июня 2016

Причина ошибки: в объектно-ориентированном языке программирования ноль означает отсутствие ссылки на объект.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 #.

2 голосов
/ 23 мая 2011

Вам нужно проверить на DBNull, а не null. Кроме того, два из ваших трех ReplaceNull методов не имеют смысла. double и DateTime не обнуляются, поэтому проверка их на null всегда будет false ...

1 голос
/ 27 марта 2014

TryParse - обычно самый элегантный способ справиться с вещами такого типа:

long temp = 0;
if (Int64.TryParse(dataAccCom.GetParameterValue(IDbCmd, "op_Id").ToString(), out temp))
{
   DataTO.Id = temp;
}     
0 голосов
/ 02 июля 2019

Я столкнулся с этой проблемой сегодня и решил ее, проверив класс отображения. У меня был класс, который имел 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

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 02 июня 2017

Для других, которые приходят на эту страницу из Google:

DataRow также имеет функцию .IsNull("ColumnName")

    public DateTime? TestDt; 
    public Parse(DataRow row)
    {
        if (!row.IsNull("TEST_DT"))
            TestDt = Convert.ToDateTime(row["TEST_DT"]);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...