对于int字段,SqlDataReader返回空白而不是null

时间:2016-01-21 17:08:32

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

我正在使用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且字段为reader["Column1Name"],为什么null会返回空白而不是int

2 个答案:

答案 0 :(得分:4)

  

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

实际上,如果数据库值为NULL,reader["Column1Name"]将返回DBNull.Value。 (在Visual Studio调试器中,该值显示为空白,因为DBNull.ToString()返回空字符串。)您无法使用强制转换操作符将DBNull.Value直接强制转换为int?

  

那么调用IsDBNull方法是否有更简单的方法?

是的,请使用as运算符代替强制转换:

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

由于DBNull.Value不是intas运算符会返回null

答案 1 :(得分:0)

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);
}