SqlDataReader gibt leer anstelle von null für ein int-Feld zurück

Ich verwende SqlDataReader, um data aus einer SQL server 2012 database zu holen:

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"]; } } 

Beim Lesen eines NULL int Feldes aus der database ist der reader["Column1Name"] leer, so dass der Code zur Laufzeit eine InvalidCastException austriggers.

Ich habe versucht

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

aber das wirft System.Data.SqlTypes.SqlNullValueException.

Ich habe auch versucht

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

die null zurückgibt, aber der Typ ist SqlInt32 und nicht int? wie ich will

Ich habe am Ende gemacht

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

was funktioniert

Fragen:

  1. Gibt es keinen einfacheren path als das Aufrufen der IsDBNull Methode?

  2. Warum ist reader["Column1Name"] leer statt null wenn der db-Wert NULL ist und das Feld ein int ?

Warum ist reader["Column1Name"] leer statt Null, wenn der db-Wert null ist und das Feld ein int ?

Eigentlich gibt der reader["Column1Name"] DBNull.Value zurück, wenn der databasewert NULL ist. (Im Visual Studio-Debugger scheint der Wert leer zu sein, da DBNull.ToString () einen leeren String zurückgibt.) Sie können DBNull.Value direkt auf int? mit dem Cast-Operator.

Gibt es da keinen einfacheren path und ruft dann die Methode IsDBNull ?

Ja, benutze den Operator anstelle eines Cast:

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

Da DBNull.Value kein int , gibt der Operator null .

C # kann keinen String zu einem int? mit (int?). Der sicherste path ist, den bedingten Operator zu verwenden, um auf Null zu prüfen, dann manuell den Wert auf Null setzen.

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

Ähnlich, wenn Sie nicht null datatypen haben, können Sie sie auf Null prüfen und sie auf ihre Standardwerte setzen.

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