2011-04-10 3 views
9

Comment ajouter des valeurs qu'un SqlDataReader retourne à une liste générique? J'ai une méthode où j'utilise SqlDataReader pour obtenir CategoryID à partir d'un tableau Category. Je voudrais ajouter tous les CategoryID une liste générique.C# - Remplir la liste générique de SqlDataReader

Cette dose ne fonctionne pas car elle renvoie seulement un categoryID et c'est le dernier. Je veux ajouter tous les categoryID à la liste, puis les retourner.

Comment faire cela?

SqlConnection connection = null; 
SqlDataReader reader = null; 
SqlCommand cmd = null; 

try 
{ 
    connection = new SqlConnection(connectionString); 
    cmd = new SqlCommand("select CategoryID from Categories", connection); 

    connection.Open(); 

    List<int> catID = new List<int>(); 
    dr = cmd.ExecuteReader(); 
    while (dr.Read()) 
    { 
     catID.Add(Convert.ToInt32(dr["CategoryID"].ToString())); 
    } 
} 
finally 
{ 
    if (connection != null) 
     connection.Close(); 
} 
return catID; 
+0

Ne pas appeler '.ToString()'. – SLaks

+0

Avez-vous un ** champ ** nommé 'catId'? – SLaks

+0

Utilisez des instructions autour de la connexion, de la commande et du lecteur! – RQDQ

Répondre

3

Votre code actuel devrait fonctionner, en supposant catID est vraiment déclaré avant que le bloc d'essai, sinon ce ne sera pas compiler.

+0

catID est déclaré. Quand je teste mon code, je ne récupère qu'un seul CategoryID au lieu de quatre que j'ai dans ma table. – Erik

+2

@Erik: Pouvez-vous mettre à jour votre exemple de code avec le code * real * que vous exécutez, vous pourriez être en train de sortir de la liste à chaque fois, mais le code ci-dessus n'est clairement pas ce que vous utilisez actuellement. – BrokenGlass

+0

@Erik - oui, c'est déclaré - juste au mauvais endroit ci-dessus. – RQDQ

13

Essayez comme ça, il vaut mieux, plus sûr, utilise le chargement paresseux, moins de code, de travail, ...:

public IEnumerable<int> GetIds() 
{ 
    using (var connection = new SqlConnection(connectionString)) 
    using (var cmd = connection.CreateCommand()) 
    { 
     connection.Open(); 
     cmd.CommandText = "select CategoryID from Categories"; 
     using (var reader = cmd.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       yield return reader.GetInt32(reader.GetOrdinal("CategoryID")); 
      } 
     } 
    } 
} 

puis:

List<int> catIds = GetIds().ToList(); 
+0

@Darim: Bien que j'aime ce code, il incomberait au consommateur d'appeler 'ToList()' - sinon vous avez une connexion DB ouverte. Je ne suis pas convaincu paresseux est la bonne approche ici. – BrokenGlass

+2

@BrokenGlass no. la connexion, le lecteur, tous ces trucs se ferment une fois que foreach est sorti. Mis à part le mérite de ceci, un inconvénient serait que l'appelant devra relire les données de la base de données si vous devez réutiliser les objets dans IEnumerable et si vous ne les avez pas tous stockés quelque part déjà. Je veux dire au cas où vous ne "foreach" pleinement. Avec 'ToList()' vous les avez déjà quelque part .. – nawfal

+0

'GetOrdnal' n'est vraiment pas nécessaire, en particulier lorsque la requête est une seule colonne comme celle-ci,' reader.GetOrdinal ("CategoryID") 'peut simplement être remplacé par' 0 ' –

1

AS BrokenGlass a expliqué c'est la démonstration

SqlConnection connection = null; 
     SqlDataReader dr= null; 
     SqlCommand cmd = null; 
List<int> catID = new List<int>(); 
     try 
     { 
      connection = new SqlConnection(connectionString); 
      cmd = new SqlCommand("select CategoryID from Categories", connection); 

      connection.Open(); 



      dr = cmd.ExecuteReader(); 
      while (dr.Read()) 
      { 
       catID.Add(Convert.ToInt32(dr["CategoryID"].ToString())); 
      } 


     } 
     finally 
     { 
      if (connection != null) 
       connection.Close(); 
     } 
     return catID; 

ainsi que vous changez la déclaration

SqlDataReader reader = null; 

à

SqlDataReader dr= null; // Because you are using dr in the code not reader 
0

Cela devrait fonctionner, mais je vous suggère d'utiliser using avec votre connections

SqlConnection connection = null; 
    SqlDataReader reader = null; 
    SqlCommand cmd = null; 
    List<int> catID = new List<int>(); 
    try 
    { 
     connection = new SqlConnection(connectionString); 
     cmd = new SqlCommand("select CategoryID from Categories", connection); 

     connection.Open(); 



     dr = cmd.ExecuteReader(); 
     while (dr.Read()) 
     { 
      catID.Add(Convert.ToInt32(dr["CategoryID"].ToString())); 
     } 


    } 
    finally 
    { 
     if (connection != null) 
      connection.Close(); 
    } 
    return catID; 
0
 List<int> s = new List<int>(); 
     conn.Open(); 
     SqlCommand command2 = conn.CreateCommand(); 
     command2.CommandText = ("select turn from Vehicle where Pagged='YES'"); 
     command2.CommandType = CommandType.Text; 
     SqlDataReader reader4 = command2.ExecuteReader(); 
     while (reader4.Read()) 
     { 
      s.Add(Convert.ToInt32((reader4["turn"]).ToString())); 
     } 
     conn.Close();