c# - Fill generic list from SqlDataReader

24,062

Solution 1

Try like this, it's better, safer, uses lazy loading, less code, working, ...:

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

and then:

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

Solution 2

Your current code should work, assuming catID is really declared before the try block, otherwise this won't compile.

Solution 3

AS BrokenGlass explained this is the demonstration

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;

as well as you change the declaration

SqlDataReader reader = null;

to

SqlDataReader dr= null; // Because you are using dr in the code not reader
Share:
24,062

Related videos on Youtube

Erik
Author by

Erik

Updated on July 09, 2022

Comments

  • Erik
    Erik almost 2 years

    How can I add values that a SqlDataReader returns to a generic List? I have a method where I use SqlDataReader to get CategoryID from a Category table. I would like to add all the CategoryID a generic List.

    This dose not work because it returns only one categoryID and that is the last one. I want to add all the categoryID to the list and then return them.

    How do I do that?

    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;
    
    • SLaks
      SLaks about 13 years
      Do you have a field named catId?
    • RQDQ
      RQDQ about 13 years
      Use using statements around the connection, command and the reader!
  • Erik
    Erik about 13 years
    catID is declared. When I test my code I only get back one CategoryID instead of four that I have in my table.
  • BrokenGlass
    BrokenGlass about 13 years
    @Erik: Can you update your sample code with the real code you are running, you might be new-ing out the list every time, but above code is clearly not what you are using currently.
  • BrokenGlass
    BrokenGlass about 13 years
    @Darim: While I like this code that would make it the responsibility of the consumer though to call ToList() - otherwise you have an open DB connection. I'm not convinced lazy is the right approach here.
  • nawfal
    nawfal about 11 years
    @BrokenGlass no. the connection, the reader, all that stuff get closed once foreach is exited. Apart from the merit of this, a drawback would be that the caller will have to re-read the data from database if you have to re-use the objects in the IEnumerable and if you haven't stored all of them somewhere already. I mean in case you do not "foreach" fully. With ToList() you already have them somewhere..
  • Scott Chamberlain
    Scott Chamberlain over 10 years
    GetOrdnal really is not necessary, especially where the query is a single column like this, reader.GetOrdinal("CategoryID") can just be replaced with 0
  • Jesuraja
    Jesuraja almost 10 years
    Can we do it for List<T>?

Related