Convert.ToInt 抛出的对象不能从 DBNull 转换为其他类型

本文关键字:转换 DBNull 其他 类型 不能 ToInt 对象 Convert | 更新日期: 2023-09-27 18:35:07

下面的代码似乎有什么问题?我认为数据库中有空,如何对包含空的列求和?

int Total_QtyinHand = 0;
int Total_QtyAllocated = 0;
int Total_QtyinStock = 0;
int Total_QtyUpcoming = 0;
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // VVV  --- Exception happens on the line below --- VVV
        Total_QtyinHand += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "QuantityonHand"));
        Total_QtyAllocated += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "Allocated_Quantity"));
        Total_QtyinStock += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "Qty_in_Stock"));
        Total_QtyUpcoming += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "UpcomingStock"));
    }
    else if (e.Row.RowType == DataControlRowType.Footer)
    {
        e.Row.Cells[3].Text = "Total Qty";
        e.Row.Cells[3].Font.Bold = true;
        e.Row.Cells[4].Text = Total_QtyinHand.ToString();
        e.Row.Cells[4].Font.Bold = true;
        e.Row.Cells[5].Text = Total_QtyAllocated.ToString();
        e.Row.Cells[5].Font.Bold = true;
        e.Row.Cells[6].Text = Total_QtyUpcoming.ToString();
        e.Row.Cells[6].Font.Bold = true;
    }
}

Convert.ToInt 抛出的对象不能从 DBNull 转换为其他类型

使用数据库 API 时,如果数据库中的值为 null,则值将替换为 DBNull.Value。您的代码尝试将其直接转换为失败的 int。将值直接与null进行比较也无济于事,因为该值不是null,而是DBNull.Value

所以:

object value = DataBinder.Eval(e.Row.DataItem, "QuantityonHand");
if (value != DBNull.Value) { Total_QtyinHand += (int)value; }

或者,如果该值实际上是后台的字符串,则可能需要对其进行解析。不过,最好升级数据库的架构以实际存储并返回数值,稍后会详细介绍:

object value = DataBinder.Eval(e.Row.DataItem, "QuantityonHand");
if (value != DBNull.Value)
{ 
    int result = -1;
    if (int.TryParse((string)value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
    {
       Total_QtyinHand += result;
    }
}

当然,您可以在单独的函数中捕获此逻辑,或者使用 ?: 运算符:

object value = DataBinder.Eval(e.Row.DataItem, "QuantityonHand");
Total_QtyinHand += (value == DBNull.Value ? 0 : (int)value);

在研究答案时,您可能会发现很多建议,通过字符串往返值并再次解析它。这可能会导致非常奇怪的行为,我强烈建议不要这样做。我过去甚至写过一个FxCoprule来捕捉代码中的这些窃听器。如果您的架构是正确的,则数据库中的值已经是数字格式,并且没有理由在文化解析沙子中引入各种怪异行为。使用 .Parse.TryParse 方法时,请确保为其提供预期的 NumberStyle 和存储数字的区域性,以防止意外分析错误(例如,如果小数分隔符设置不正确,则将值乘以 100)。

这段代码在我的测试中工作正常

tot += DataBinder.Eval(e.Row.DataItem, "mylab").ToString() != string.Empty 
    ? Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "mylab")) 
    : 0;
e.Row.Cells[0].Text = tot.ToString();
相关文章: