Reputation: 300
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?
Upvotes: 0
Views: 3790
Reputation: 216293
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())
{
.....
}
}
Upvotes: 2
Reputation: 38608
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]),
});
}
Upvotes: 0