无法将类型为"System.DBNull"的对象强制转换为"System.String"

Sai*_*han 99 c# database asp.net null

我的应用程序中出现上述错误.这是原始代码

public string GetCustomerNumber(Guid id)
{
     string accountNumber = 
          (string)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidmyApp, 
                          CommandType.StoredProcedure, 
                          "GetCustomerNumber", 
                          new SqlParameter("@id", id));
     return accountNumber.ToString();
 }
Run Code Online (Sandbox Code Playgroud)

我替换了

public string GetCustomerNumber(Guid id)
{
   object accountNumber =  
          (object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM, 
                                CommandType.StoredProcedure, 
                                "spx_GetCustomerNumber", 
                                new SqlParameter("@id", id));
    if (accountNumber is System.DBNull)
    {
       return string.Empty;
    }
    else
    {
       return accountNumber.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

这有更好的方法吗?

rei*_*ein 186

通过简单的通用功能,您可以轻松完成.这样做:

return ConvertFromDBVal<string>(accountNumber);
Run Code Online (Sandbox Code Playgroud)

使用功能:

public static T ConvertFromDBVal<T>(object obj)
{
    if (obj == null || obj == DBNull.Value)
    {
        return default(T); // returns the default value for the type
    }
    else
    {
        return (T)obj;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您尝试将1转换为bool(Convert.ToBoolean(1)工作正常),这将无效 (3认同)
  • @Jaime这个函数应该像从SQL数据类型到C#/ .NET数据类型的隐式转换.如果您需要显式强制转换,请不要使用此函数 - 而是明确地执行此操作. (2认同)

Use*_*ser 82

可以使用更短的形式:

return (accountNumber == DBNull.Value) ? string.Empty : accountNumber.ToString()
Run Code Online (Sandbox Code Playgroud)

编辑:没有注意ExecuteScalar.如果返回结果中没有该字段,它确实返回null.所以改用:

return (accountNumber == null) ? string.Empty : accountNumber.ToString() 
Run Code Online (Sandbox Code Playgroud)

  • 这不起作用 - "accountNumber"不是*数据库值,而是常规旧的Plain Old .NET"对象"实例 - 您需要检查正常的"null"值.DBNull.Value适用于SqlDataReader或SqlParameter - 但不适用于此对象. (3认同)

Joe*_*Joe 15

ExecuteScalar将返回

  • 如果没有结果集,则返回null
  • 否则结果集的第一行的第一列,可能是DBNull.

如果您知道结果集的第一列是字符串,那么要覆盖所有需要检查null和DBNull的基数.就像是:

object accountNumber = ...ExecuteScalar(...);
return (accountNumber == null) ? String.Empty : accountNumber.ToString();
Run Code Online (Sandbox Code Playgroud)

上面的代码依赖于DBNull.ToString返回空字符串的事实.

如果accountNumber是另一种类型(比如整数),那么你需要更明确:

object accountNumber = ...ExecuteScalar(...);
return (accountNumber == null || Convert.IsDBNull(accountNumber) ?     
         (int) accountNumber : 0;
Run Code Online (Sandbox Code Playgroud)

如果您确定结果集总是至少有一行(例如SELECT COUNT(*)...),那么您可以跳过检查null.

在您的情况下,错误消息"无法将类型'System.DBNull'的对象强制转换为'System.String`"表示结果集的第一列是DBNUll值.这是从第一行的强制转换为字符串:

string accountNumber = (string) ... ExecuteScalar(...);
Run Code Online (Sandbox Code Playgroud)

Marc_s的注释,你不需要检查DBNull.Value是错误的.


Nat*_*oop 6

您可以使用C#的空合并运算符

return accountNumber ?? string.Empty;
Run Code Online (Sandbox Code Playgroud)

  • return Cmd.ExecuteScalar().ToString()?? 的String.Empty; (2认同)