12

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;
2
  • Do you have a field named catId? Commented Apr 10, 2011 at 16:51
  • Use using statements around the connection, command and the reader! Commented Apr 10, 2011 at 16:51

5 Answers 5

15

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();
Sign up to request clarification or add additional context in comments.

4 Comments

@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.
@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..
GetOrdnal really is not necessary, especially where the query is a single column like this, reader.GetOrdinal("CategoryID") can just be replaced with 0
Can we do it for List<T>?
3

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

2 Comments

catID is declared. When I test my code I only get back one CategoryID instead of four that I have in my table.
@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.
1

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

Comments

0

This should work but I suggest you to use using with your 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;

Comments

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();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.