2009-09-04 8 views
1

des boucles sur un type DataRow et tels que rencontrent desQuelle est la méthode recommandée pour commencer à utiliser des types à partir d'un DataRow retourné en C#?

DataRow dr; 
dr["someString"] 
dr["someInteger"] 
dr["somedata"] 

Quelle est la meilleure façon de les obtenir dans leurs types de données correspondants? dr ["foo"] est juste un objet générique.

Aussi, sont-ils capables d'être facilement convertis en types nullable? dr ["someInteger"] pourrait être nul.

Répondre

8

Dans un DataRow, lorsqu'une valeur est nulle, elle n'est pas égale à null: elle est égale à DBNull.Value. À moins que vous sachiez que votre champ ne peut pas être nul, il n'est pas sûr de lancer. Par exemple, l'exemple suivant échouera si les données sont DBNull:

string name = (string)dr["Name"]; 

Si vous pouvez utiliser les extensions LINQ, vous pouvez inclure la référence System.Data.DataSetExtensions et l'espace de noms System.Data et appelez

string name = dr.Field<string>("Name"); 

Si vous ne peut pas utiliser LINQ, alors vous devez revenir à vérifier la valeur null avec

string name = null; 
if(!dr.IsNull("Name")) 
    name = (string)dr["Name"]; 

Ou vous pouvez coder votre propre fonction de champ comme thi s:

public static T GetValue<T>(object value) 
{ 
    if (value == null || value == DBNull.Value) 
     return default(T); 
    else 
     return (T)value; 
} 

et obtenir votre valeur de cette façon:

string name = GetValue<string>(dr["Name"]); 
+0

Que se passe-t-il si vous appelez int i = dr.Field ("someintcolumn"); et la ligne est nulle? –

+0

Le champ () est assez brillant pour renvoyer la valeur par défaut (T), donc votre variable i sera égale à 0 si la donnée est nulle. –

+1

+1 pour la rigueur et prendre le temps de couvrir les nulls. – womp

2

casting simplement les valeurs du type droit devrait fonctionner:

(string) dr["someString"]; 
(int?) dr["someInteger"]; 
(byte[]) dr["somedata"]; 
+1

Attention, '(int?) Dr [ "someInteger"];' échouera si la valeur est DBNull. –

+0

Y a-t-il un avantage à lancer des versets appelant int.Parse() par exemple? – Gratzy

+0

Existe-t-il un raccourci pour que (int?) Fonctionne. Je pense quelque chose comme int? .TryParse (dr ["some"])? (int?) dr ["some"]: null –

3

Si vous pouvez utiliser .NET 3.5, vous pouvez utiliser le Field extension method pour accéder plus facilement les données si vous connaissez le type. Un exemple serait:

string somestring= row.Field<string>("SomeString"); 

Sinon, vous êtes coincé avec la projection du champ au type de l'objet à l'ancienne. Lors de la lecture d'un DataRow, votre plus grand ennemi est une valeur nulle.

+0

Je suis coincé. Merci :) –

0
string GetString(DataRow dr, string ColumnName) 
{ 
    if (dr.IsNull(ColumnName)) 
    { 
     return null; 
    } 
    return (string)dr[ColumnName]; 
} 
+0

Cela n'aurait-il pas plus de sens de renvoyer une chaîne vide au lieu de null ici? – Mike

+0

Peut-être, mais il peut aussi y avoir "" dans la valeur de la colonne, donc vous devez différencier en quelque sorte. Cela dépend de comment vous aimez/avez besoin. –

0

Une autre option est d'utiliser "comme"

string str = dr["someString"] as string; 

si elle est DBNull.Value (ou tout autre objet pas de type string), alors str obtiendra un vrai "null". Sinon, il obtiendra la valeur de chaîne appropriée.

Pour les types de valeur, vous pouvez utiliser annulable, à savoir

int? i = dr["someint"] as int?; 

Encore une fois, il obtiendra un véritable "nulle" au lieu de DBNull.Value. Cependant, avec les types nullables vous devez vous rappeler d'utiliser .Value, à savoir

int x = i.Value + 5; 
+0

int? i = 3; int x = i + 5; ne fonctionnera pas? Bizarre! Je n'ai jamais su ça. –

+0

ne compilera même pas – JoelFan

Questions connexes