Il y a beaucoup de réponses ici avec des informations utiles (et des informations erronées) répandues, j'aimerais rassembler tout cela.
La réponse courte à la question est de vérifier DBNull - presque tout le monde est d'accord sur ce bit :)
Plutôt que d'utiliser une méthode d'aide pour lire les valeurs nullables par type de données SQL, une méthode générique nous permet de résoudre ce problème avec beaucoup moins de code. Cependant, vous ne pouvez pas avoir une seule méthode générique pour les types de valeur nullable et les types de référence, cela est longuement discuté dans le
type Nullable comme paramètre générique possible? et contrainte de type générique C # pour tout ce qui peut être annulé .
Donc, à la suite des réponses de @ZXX et @getpsyched, nous nous retrouvons avec cela, 2 méthodes pour obtenir des valeurs Nullable et j'ai ajouté une 3ème pour les valeurs non Null (elle complète l'ensemble basé sur la dénomination des méthodes).
public static T? GetNullableValueType<T>(this SqlDataReader sqlDataReader, string columnName) where T : struct
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.IsDBNull(columnOrdinal) ? (T?)null : sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
public static T GetNullableReferenceType<T>(this SqlDataReader sqlDataReader, string columnName) where T : class
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.IsDBNull(columnOrdinal) ? null : sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
public static T GetNonNullValue<T>(this SqlDataReader sqlDataReader, string columnName)
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
J'utilise généralement des noms de colonnes, modifiez-les si vous utilisez des index de colonnes. Sur la base de ces noms de méthode, je peux dire si je m'attends à ce que les données soient nulles ou non, ce qui est très utile lorsque l'on regarde du code écrit il y a longtemps.
Conseils;
- Ne pas avoir de colonnes nullables dans la base de données évite ce problème. Si vous avez le contrôle sur la base de données, les colonnes doivent être non nulles par défaut et uniquement nullables si nécessaire.
- Ne convertissez pas les valeurs de la base de données avec l'opérateur C # 'as' car si le transtypage est incorrect, il retournera silencieusement null.
- L'utilisation d'une expression de valeur par défaut modifie les valeurs nulles de la base de données en valeurs non nulles pour les types de valeur tels que int, datetime, bit, etc.
Enfin, en testant les méthodes ci-dessus sur tous les types de données SQL Server, j'ai découvert que vous ne pouvez pas obtenir directement un char [] d'un SqlDataReader, si vous voulez un char [], vous devrez obtenir une chaîne et utiliser ToCharArray ().
int colIndex = reader.GetOrdinal(fieldname);
et surcharger facilement laSafeGetString
fonction de @ marc_s .