0

I am using a SqlDataReader to fetch data from a stored procedure. Even though the records are being fetched, the while (reader.Read()) gets executed only once, and so in my list only one row is added.

List<Student> tablelist = new List<Student>();

using (SqlConnection con = new SqlConnection(connectionString))
{
    using (SqlCommand cmd = new SqlCommand("SP_ReadPromotedStudents"))
    {
        cmd.Connection = con;
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = Data[0];
        cmd.Parameters.Add("@Email", SqlDbType.VarChar).Value = Data[1];
        cmd.Parameters.Add("@Class", SqlDbType.VarChar).Value = Data[2];

        con.Open();

        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.HasRows)
            {
                 while (reader.Read())
                 {
                     tablelist.Add(new Student
                                    {
                                        Name = (string)(reader[0]),
                                        Email = (string)(reader[1]),
                                        Class = (string)(reader[2]),
                                    });
                     reader.NextResult();
                 }
             }
         }
     }
}

return tablelist;

My Student class:

public class Student
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Class { get; set; }
}

I have about 46 records being fetched. But in the list only one record gets added. What is the mistake here?

4
  • 3
    Why do you use NextResult ? Commented Jun 8, 2020 at 17:26
  • NextResult() moves to the next result set, not the next row. Take that out. Commented Jun 8, 2020 at 17:27
  • Without NextResult(), it is going into infinte while loop. It is stuck at while (reader.Read()) Commented Jun 8, 2020 at 17:33
  • You should not loop while reader HasRows, you should use if not while. Commented Jun 8, 2020 at 18:46

2 Answers 2

2

You need to move your call to NextResult outside the reader.Read() loop. Otherwise after the first read the code encounters the NextResult call and tries to load a second sets of data returned by the stored procedure.

Also the loop over HasRows is an infinite loop. If the property reader.HasRows is true it will be true also when you finish to read the rows.

using (SqlDataReader reader = cmd.ExecuteReader())
{
    while (reader.Read())
    {
        tablelist.Add(new Student
        {
            Name = (string)(reader[0]),
            Email = (string)(reader[1]),
            Class = (string)(reader[2]),
        });
    }

    // This should be called only if your stored procedure returns 
    // two or more sets of data otherwise you can remove everything
    reader.NextResult();

    // If there is another set of data then you can read it with a
    // second while loop with
    while(reader.Read())
    {
        .....
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

if(!reader.HasRows()) return; should be added as a cutout after the using block. You will release resources significantly sooner and prevent inevitable NullReferenceException errors downstream
0

The ideal scenario would to have a new sql statement to get just what you want instead the get a list and need just the first access. Imagine if you have a table with millions of records, would you need to execute a query to get all and read just the first one? No, you execute a query to get the you need.

The NextResult method from DataReader moves the pointer to the next result if you have it on the result. Remove it.

After you chanfge the sql statement to get what you need, you are looping the result set. You could read just the first line (changing the while to if):

if (reader.Read())
{
   tablelist.Add(new Student
   {
     Name = (string)(reader[0]),
     Email = (string)(reader[1]),
     Class = (string)(reader[2]),
   });
}

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.