【问题标题】:SqlDataReader returns blank instead of null for an int fieldSqlDataReader 为 int 字段返回空白而不是 null
【发布时间】:2016-01-21 17:08:32
【问题描述】:

我正在使用 SqlDataReader 从 SQL Server 2012 数据库中获取数据:

SqlConnection connection = (SqlConnection)_db.Database.GetDbConnection();
await connection.OpenAsync();
SqlCommand command = new SqlCommand("dbo.[sp_MyStoredPrc] @InputId=1", connection);
var reader = await command.ExecuteReaderAsync();

if (reader.HasRows)
{
    while (reader.Read())
    {
        int? var1 = (int?)reader["Column1Name"];
    }
}

从数据库中读取 NULL int 字段时, reader["Column1Name"] 为空白,因此代码在运行时抛出 InvalidCastException。

我试过了

reader.GetInt32(reader.GetOrdinal("Column1Name"))

但这会引发 System.Data.SqlTypes.SqlNullValueException。

我也试过

reader.GetSqlInt32(reader.GetOrdinal("Column1Name"))

返回 null,但类型是 SqlInt32,而不是我想要的 int?

我最终做了

if (!reader.IsDBNull(reader.GetOrdinal("Column1Name"))) 
    int? var1 = (int?)reader["Column1Name"];

哪个有效。

问题:

  1. 难道没有比调用IsDBNull 方法更简单的方法吗?

  2. 如果 db 值为 NULL 且字段为 int,为什么 reader["Column1Name"] 返回空白而不是 null

【问题讨论】:

  • 我不确定但尝试使用 Convert.ToInt32(reader["Column1Name"]);
  • 我得到一个异常,因为 Reader["Column1Name"] 是空白的
  • 您确定 db 值为空吗?它可以为空,但并不意味着它为空。否则没有比检查空值更简单的方法来处理它。
  • 我确定它为 null 我可以执行 SQL 分析器跟踪以查看 ti 返回 null。另外 reader.GetSqlInt32(reader.GetOrdinal("Column1Name")) 返回 null
  • 感谢您的澄清。另外,Column1Name 和 ColumnName1 是不同的字段吗?

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


【解决方案1】:

如果 db 值为 null 且字段为 int,为什么 reader["Column1Name"] 返回空白而不是 null?

实际上,如果数据库值为 NULL,reader["Column1Name"] 会返回 DBNull.Value。 (在 Visual Studio 调试器中,该值显示为空白,因为 DBNull.ToString() 返回一个空字符串。)您不能使用 cast 运算符将 DBNull.Value 直接转换为 int?

难道没有比调用IsDBNull 方法更简单的方法吗?

是的,使用 as 运算符而不是强制转换:

int? var1 = reader["Column1Name"] as int?;

因为DBNull.Value 不是int,所以as 运算符返回null

【讨论】:

    【解决方案2】:

    C# 不能将字符串转换为 int?使用(int?)。最安全的方法是使用条件运算符检查是否为null,然后手动将值设置为null。

    //Get the column index to prevent calling GetOrdinal twice
    int COLUMNNAME1 = reader.GetOrdinal("ColumnName1");
    
    while (reader.Read())
    {
        int? var1 = reader.IsDBNull(COLUMNNAME1) ? null : reader.GetInt32(COLUMNNAME1);
    }
    

    同样,如果您有非 null 数据类型,您可以检查它们是否为 null 并将它们设置为默认值。

    int STRINGCOLUMN = reader.GetOrdinal("StringColumn");
    int INTCOLUMN = reader.GetOrdinal("IntColumn");
    int DATECOLUMN = reader.GetOrdinal("DateColumn");
    int BOOLCOLUMN = reader.GetOrdinal("BoolColumn");
    
    while (reader.Read())
    {
        string var1 = reader.IsDBNull(STRINGCOLUMN) ? "" : reader.GetString(STRINGCOLUMN);
        int var2 = reader.IsDBNull(INTCOLUMN) ? 0 : reader.GetInt32(INTCOLUMN);
        DateTime var3 = reader.IsDBNull(DATECOLUMN) ? DateTime.MinValue : reader.GetDateTime(DATECOLUMN);
        bool var4 = reader.IsDBNull(BOOLCOLUMN) ? false : reader.GetBoolean(BOOLCOLUMN);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-14
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 2013-10-13
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多