C# 尝试强制转换空值时引发异常

C# 尝试强制转换空值时引发异常,c#,winforms,C#,Winforms,我有一个查询,从DataTable中的数据库接收信息: DataTable estimateCalculation = new DataTable(); estimateCalculation = db.ExeSQLEstimate("usp_Contracted_Calculation", param1, param2); 现在我得到的值是: var averageContractedAmount = (from DataRow dr in estimateCalculation.Row

我有一个查询,从
DataTable
中的数据库接收信息:

DataTable estimateCalculation = new DataTable();

estimateCalculation = db.ExeSQLEstimate("usp_Contracted_Calculation", param1, param2);
现在我得到的值是:

 var averageContractedAmount = (from DataRow dr in estimateCalculation.Rows select (decimal)dr["AverageContractedAmount"]).FirstOrDefault().ToString("C");
但在某些情况下,
dr
可以为空,因此会引发异常

System.InvalidCastException:'指定的转换无效


如果
dr
返回null,我如何验证它,而不是尝试将其转换为十进制?

我想您需要这样简单的东西。如果我误解了,请澄清。(也欢迎)

这也值得一看


我自己没有使用过这个,但看起来它可能非常适合您所寻找的内容。

您基本上有3个选项来执行空检查:

  • 调用
    DataRow.IsNull()

  • 将值与
    DbNull.value
    进行比较。请注意,当数据库中的列包含null时,
    DataRow[“ColumnName”]
    不会返回
    null
    ,而是返回
    DbNull.Value

    var value = (from DataRow dr in estimateCalculation.Rows select dr["AverageContractedAmount"]).FirstOrDefault();
    
    if (value != null && value != DBNull.Value)
    {
        var averageContractedAmount = ((decimal)value).ToString("C");
    }
    
  • 执行值的运行时类型检查。当与C#7.0模式匹配语法一起使用时,这尤其好:

    if ((from DataRow dr in estimateCalculation.Rows select dr["AverageContractedAmount"]).FirstOrDefault() is decimal value)
    {
        var averageContractedAmount = value.ToString("C");
    }
    
  • 有时您不想执行
    if-else
    分支,只想将值转换为可为null的类型,通常使用三元条件运算符:

    var averageContractedAmount = 
        (from DataRow dr in estimateCalculation.Rows
         select (dr.IsNull("Price")
                    ? null
                    : (decimal?)dr["AverageContractedAmount"])
        ).FirstOrDefault()
        ?.ToString("C");
    

    我认为这不应该是可行的,因为我接收对象,我的意思是[0],但值是
    {}
    ,就像一个空的string@Pepe您的过程返回一行数据,对吗?我尝试使用
    if(estimateCalculation.Rows==DBNull.Value)
    ,但是不能在datarow集合中使用DBNull.Value,并且它只返回一个rowRows是集合,所以我认为DBNull.Value不起作用。但是,if语句与行计数相同。如果proc返回零行,那么它实际上是空的(ish),因此,行计数在该速率下是理想的。您需要将
    dr[“AverageContractedAmount”]
    ,而不是
    EstimateColution.rows
    ,与
    DBNull
    进行比较。看见
    var value = (from DataRow dr in estimateCalculation.Rows select dr["AverageContractedAmount"]).FirstOrDefault();
    
    if (value != null && value != DBNull.Value)
    {
        var averageContractedAmount = ((decimal)value).ToString("C");
    }
    
    if ((from DataRow dr in estimateCalculation.Rows select dr["AverageContractedAmount"]).FirstOrDefault() is decimal value)
    {
        var averageContractedAmount = value.ToString("C");
    }
    
    var averageContractedAmount = 
        (from DataRow dr in estimateCalculation.Rows
         select (dr.IsNull("Price")
                    ? null
                    : (decimal?)dr["AverageContractedAmount"])
        ).FirstOrDefault()
        ?.ToString("C");