【问题标题】:Cast to int on SqlCommand-ExecuteScalar error handling在 SqlCommand-ExecuteScalar 错误处理上强制转换为 int
【发布时间】:2015-12-06 07:06:48
【问题描述】:

我的代码可能很脆弱。这里声明

 int countDis = (int)cmd.ExecuteScalar();

如果我将存储过程更改为不返回任何内容,那么转换为(int) 将会失败。如果我只是删除它,那么我无法编译。

在这种情况下,防御性编码的最佳代码实践是什么?

【问题讨论】:

标签: c# sql sql-server ado.net


【解决方案1】:

如果您将DBNull.Value 的结果视为与null 相同,因为它们都应该是0,您可以使用单行,尽管您仍然使用临时变量。执行速度我就不说了:

int countDis = int.TryParse(cmd.ExecuteScalar()?.ToString(), out int temp) ? temp : 0

【讨论】:

    【解决方案2】:

    只需将代码更改为:

    int countDis = Convert.ToInt32(cmd.ExecuteScalar());
    

    这将确保即使ExecuteScalar 返回null,由于未在存储过程中选择任何内容,countDis 的值也会为0。因为Convert.ToInt32(null) = 0

    更新(2018 年 10 月 12 日)

    更安全的版本。感谢@Moe 突出显示DBNull 案例。

    object result = cmd.ExecuteScalar();
    result = (result == DBNull.Value) ? null : result;
    int countDis = Convert.ToInt32(result);
    

    【讨论】:

    • 如果结果集中有行,ExecuteScalar 可以返回 DBNull.Value,但列的值为数据库 NULL。在这种情况下,将使用上述代码引发 InvalidCastException。如果结果集中没有可从中提取列值的行,则 ExecuteScalar 可以返回 null(即 C# null)。
    【解决方案3】:

    因为 ExecuteScalar 可以返回 DBNull,所以我找到的最好方法是:

     var result = cmd.ExecuteScalar();
     int countDis = result != null ? Convert.ToInt32(result) : 0;
    

    【讨论】:

      【解决方案4】:

      我通常使用可为空的类型。例如:

      string str;
      
      int? countDis = cmd.ExecuteScalar() as int?;
      if (countDis == null)
         str = "count is null";
      else
         str = "Count is : " + countDis.Value;
      

      这适用于 ExecuteScalar 返回 null 还是 DBNull.Value。

      【讨论】:

        【解决方案5】:

        您可以使用作为对象获取,并检查其类型然后做出决定:

                object obj = cmd.ExecuteScalar();
                if (obj.GetType() == typeof(string))
                {
                    //you can do your stuff with STRING
                }
                else if (obj.GetType() == typeof(int))
                {
                    //you can do your stuff with INT
                }
                else
                {
                    //add here ANYOTHER type you many want in future...
                }
        

        【讨论】:

        • 敏捷方法会说您应该只针对当前问题进行编码。这也被称为 YAGNI(你不需要它)原则。
        • 当然,我个人也不喜欢这个,只是放在这里给@MillRunner一个想法
        【解决方案6】:

        您可以在转换前检查标量值。

        var result = cmd.ExecuteScalar();
        int countDis =result != null ? int.Parse(result) : 0;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-12
          • 1970-01-01
          • 2017-11-25
          • 1970-01-01
          • 1970-01-01
          • 2011-02-21
          • 1970-01-01
          相关资源
          最近更新 更多