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;
}
}
使用数据库 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();