2016-01-21 2 views
4

Я использую SqlDataReader для извлечения данных из SQL Server 2012 базов данных:SqlDataReader возвращает пустые вместо нуля для поля Int

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")) 

который возвращает нуль, но тип SqlInt32 и не int?, как я хочу.

я в конечном итоге делает

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

, который работает.

Вопросы:

  1. не более простой способ, чем вызов метода IsDBNull?

  2. Почему reader["Column1Name"] возвращение пустым вместо null, если значение дб NULL и поле является int?

+0

Я не уверен, но попытаюсь использовать Convert.ToInt32 (reader ["Column1Name"]); – SergeyAn

+0

Я получаю исключение, потому что Reader ["Column1Name"] пуст – devc2

+0

Вы уверены, что значение db равно null? Он может быть пустым, но это не значит, что он равен нулю. В противном случае нет простого способа справиться с этим, чем проверить пустое значение. – SergeyAn

ответ

4

Почему reader["Column1Name"] возврата заготовки вместо NULL, если значение децибел равно нулю, и поле является int?

Фактически, reader["Column1Name"] возвращает DBNull.Value, если значение базы данных равно NULL. (В отладчике Visual Studio значение выглядит пустым, потому что DBNull.ToString() возвращает пустую строку.) Вы не можете использовать DBNull.Value непосредственно int? с помощью оператора трансляции.

Не существует ли более простой способ вызова метода IsDBNull?

Да, используйте оператор as вместо броска:

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

Поскольку DBNull.Value не является int, оператор as возвращает null.

0

C# не может передать строку в int? используя (int?). Самый безопасный способ - использовать условный оператор для проверки нулевого значения, затем вручную установить значение 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); 
} 

Аналогичным образом, если у вас есть ненулевые типы данных, вы можете проверить их на нуль и установить их значения по умолчанию.

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); 
} 
Смежные вопросы