System.InvalidCastException:无法将对象从DBNull强制转换为其他类型

Lax*_*dur 5 c# oracle

我的代码中有一个例外.我已经尝试将我的int64更改为int32,但这并没有改变它.

在数据库中,表示"column_ID"的单元格具有数据类型NUMBER.

问题出在此代码的第7行:

private void dataGridView_ArticleINVIA_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.RowIndex >= 0 && e.RowIndex <= (sender as DataGridView).Rows.Count - 1)
    {
        try
        {
            Int64 id_riga = Convert.ToInt64((sender as DataGridView).Rows[e.RowIndex].Cells["column_ID"].Value);
            //Exception thrown here:
            int id_macchina = Convert.ToInt32((sender as 
                DataGridView).Rows[e.RowIndex].Cells["column_Machine"].Value);
            FormRecipeNote PopUpNote = new FormRecipeNote(id_macchina, 
                "MODIFICA", id_riga, 0);
            PopUpNote.ShowDialog(this);
            PopUpNote.Dispose();
         }
         catch (Exception Exc)
         {
             FormMain.loggerSoftwareClient.Trace(this.Name + " " + Exc);
         }
         //DataGrid_ArticleINVIA();
    }
}
Run Code Online (Sandbox Code Playgroud)

错误是:

System.InvalidCastException: Object cannot be cast from DBNull to other types.
   at System.DBNull.System.IConvertible.ToInt64(IFormatProvider provider)
   at System.Convert.ToInt64(Object value)
   at Software_Client.FormSendReceiveRecipe.dataGridView_ArticleINVIA_CellDoubleClick(Object sender, DataGridViewCellEventArgs e)
Run Code Online (Sandbox Code Playgroud)

有人可以帮我解决这个问题吗?

Ser*_*rvy 8

正如错误消息所示,单元格的值是,DBNull.Value并且它无法从该转换为您想要的任何值(在本例中为a long或an int).您需要DBNull在转换/转换数字之前检查:

Int64 id_riga = 0;
object value = (sender as DataGridView).Rows[e.RowIndex].Cells["column_ID"].Value;
if(value != DBNull.Value) 
    id_riga = Convert.ToInt64(value);
Run Code Online (Sandbox Code Playgroud)

因为这会增加一些恼人的开销,如果你这么做,你可能想要制作一个帮助你的帮助方法.

public static long? getLongFromDB(object value)
{
    if (value == DBNull.Value) return null;
    return Convert.ToInt64(value);
}
Run Code Online (Sandbox Code Playgroud)

然后你的代码可以是:

Int64 id_riga = getLongFromDB((sender as DataGridView).Rows[e.RowIndex].Cells["column_ID"].Value)
    .GetValueOrDefault();
Run Code Online (Sandbox Code Playgroud)


Saw*_*wan 4

您可以将有问题的行更改为:

int id_macchina = ((sender as DataGridView).Rows[e.RowIndex].Cells["column_Machine"].Value as int?).GetValueOrDefault();
Run Code Online (Sandbox Code Playgroud)

id_macchina如果column_Machine数据库中列的值为空,这将为变量赋予默认值 int (0) (DBNull在 C# 中)

尝试这个:

object aa = DBNull.Value;
int a = (aa as int?).GetValueOrDefault();
Run Code Online (Sandbox Code Playgroud)

它会起作用的!如果列是 ,则该值为 0 DBNull

* 编辑 *

但是尝试使用其他东西,这可能会隐藏一些错误,例如更改数据类型,如果类型是long并且在数据库中不是int,则总是将0分配给变量,它过去发生在我身上,感谢@hvd 在他的评论中指出这一点。

  • @svick实际上,从技术上讲它是可行的。由于“DBNull”不是“int”或“int?”类型,因此转换失败,而“as”的结果是它返回“null”,而实际的“int”则成功转换。然而,它非常令人困惑,因为它给人一种它不起作用的错误印象,并且不清楚它真正在做什么,因此可读性受到很大影响。 (2认同)