在SqlCommand-ExecuteScalar错误处理上转换为int

9 c# sql sql-server ado.net

我的代码可能很脆弱.这句话在这里

 int countDis = (int)cmd.ExecuteScalar();
Run Code Online (Sandbox Code Playgroud)

如果我将存储过程更改为不返回ANYTHING,那么该转换(int)将会爆炸.如果我只是删除它,那么我无法编译.

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

Nik*_*tak 19

只需将代码更改为:

int countDis = Convert.ToInt32(cmd.ExecuteScalar());
Run Code Online (Sandbox Code Playgroud)

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

更新(10/12/2018)

更安全的版本.感谢@Moe突出DBNull案例.

object result = cmd.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int countDis = Convert.ToInt32(result);
Run Code Online (Sandbox Code Playgroud)

  • 如果结果集中有一行,则ExecuteScalar可以返回DBNull.Value,但该列的值是数据库NULL.在这种情况下,将使用上面的代码引发InvalidCastException.如果结果集中没有可从中提取列值的行,则ExecuteScalar可以返回null(即C#null). (4认同)

Moe*_*sko 5

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

string str;

int? countDis = cmd.ExecuteScalar() as int?;
if (countDis == null)
   str = "count is null";
else
   str = "Count is : " + countDis.Value;
Run Code Online (Sandbox Code Playgroud)

这将适用于 ExecuteScalar 是否返回 null 或 DBNull.Value。