C# DBNull et les Types nullables - forme de conversion les plus propres
J'ai un DataTable, qui a un certain nombre de colonnes. Certaines de ces colonnes sont les valeurs null.
DataTable dt; //Value set.
DataRow dr; //Value set.
//dr["A"] is populated from T-SQL column defined as: int NULL
Alors, quelle est la meilleure forme de la conversion d'une valeur dans un DataRow, à nullable variable.
Idéalement, je voudrais être en mesure de faire quelque chose comme:
int? a = dr["A"] as int?;
Modifier: s'avère que vous POUVEZ faire cela, les effets secondaires étant que si votre Schéma types d'arn sont pas entiers, alors c'est TOUJOURS à retourner la valeur null. La réponse par Ruben de l'aide dr.Field<int?>("A")
assure différences de type de ne pas échouer en mode silencieux. Ceci, bien sûr, va être repris par un des tests unitaires.
Au lieu de cela j'ai l'habitude de taper quelque chose le long des lignes de:
int? a = dr["A"] != DBNull.Value ? (int)dr["A"] : 0;
C'est un tas plus de frappes, mais plus important encore, il n'y a plus de place pour quelqu'un à des trucs quelque chose avec un mal de frappe.
Oui, un Test Unitaire sera de prendre cette place, mais je préfère l'arrêter complètement.
Ce qui est le plus propre, moins sujette aux erreurs de modèle pour cette situation.
- le "int? a = dr["Un"] comme d'int?;" fonctionne pour moi!
- En effet, il n'. Désolé, mal lu ce qui était souffle sur moi. Si seulement il s'agissait d'une réponse, je l'ai marqué en tant que tel.
Vous devez vous connecter pour publier un commentaire.
Le LINQ to jeux de données chapitre de LINQ in Action est une bonne lecture.
Une chose que vous verrez est la
Field<T>
méthode d'extension, qui est utilisé comme suit:-Ou
Ou
as
est certainement galvaudé - vous ne voulez pas le silence de zéros qui se passe. BTW le livre lui-même est trop bonne, mieux que le APress, bien que son difficile de battre le C# en Profondeur pour le général LINQ amorçage.DbDataReader
ouIDataReader
? Quiusing
je dois faire desField<int?>
travail?Field<T>
des choses est dans la plupart des endroits que vous attendez - à savoir, je serais surpris siIDR
/DBDR
ne l'avez pas. La clé manquante peu, comme vous faites allusion, c'est que vous devez ajouter un FW ref àSystem.Data.DataSetExtensions
-- la plupart des extensions sont à l'évidence des espaces de noms (c'est à dire, principalementSystem.Data
).C'est le but de la
DataRowExtensions
classe .NET 3.5, qui fournit statiqueField<T>
etSetField<T>
méthodes en aller-retour nullable (et non nullable) des données entre lesDataRow
et .Types de réseau.sera mis
fld
ànull
sirow["ColumnA"]
contientDBNull.Value
, de sa valeur si elle contient un nombre entier, et de lever une exception si elle contient quelque chose d'autre. Et sur le chemin du retour,fait la même chose en sens inverse: si
fld
contientnull
, il définitrow["ColumnA"]
àDBNull.Value
, et sinon, il définit à la valeur defld
.Il existe des surcharges de
Field
etSetField
pour tous les types de valeur queDataRow
prend en charge (y compris les types nullables), de sorte que vous pouvez utiliser le même mécanisme pour l'obtention et définition des champs quel que soit leur type de données.Pourquoi ne pas utiliser LINQ? Il fait la conversion pour vous.
Suivante serait de travailler en toute sécurité:
Snip:
Utilisation:
Les méthodes d'Extension!
Quelque chose comme ce qui suit:
L'utiliser comme ceci:
ou
Pour appeler la fonction, vous pouvez écrire