0

Hello I create controls from SQL via this code:

string query = "SELECT * FROM [schema] WHERE idSch=@id";
            SqlCommand com = new SqlCommand(query, con);
            com.Parameters.AddWithValue("@id", result);
            con.Open();
            SqlDataReader read= com.ExecuteReader();

            while (read.Read())
            {

                createLabelCmd((int)read["x"], (int)read["y"]);


            }
            con.Close();

The issue is that createLabelCmd contains SqlCommand and it needs an open SqlConnection

Inside createLabelCmd

String ResultSitting
private void createLabelCmd(int x, int y)
    {
for (int i = 0; i < 1; i++)
        {
            var newLabel = new Label();
            newLabel.Location = new Point(x, y);
            newLabel.Text = realpocsed.ToString();
            string sitting = newLabel.Name;
            string sittingSearch = (sitting).Substring(3, 1);
            if (sittingSearch != null && kzajezdu == "kZajezdu")
            {
                string querySitting = "SELECT name, surname FROM klient WHERE sitting = @sitting AND event=@event AND year=@year";
                SqlCommand cmdSitting = new SqlCommand(querySitting, spojeni);
                cmdSitting.Parameters.AddWithValue("@sitting", sittingSearch);
                cmdSitting.Parameters.AddWithValue("@event", idEvent);
                cmdSitting.Parameters.AddWithValue("@year", klientClass.Year());

                ResultSitting = cmdSitting.ExecuteScalar().ToString().Trim(); //This might be the issue

            }

            if (kzajezdu == "kZajezdu")
            {
                newLabel.MouseHover += delegate(object sender, EventArgs e)
                {
                    ToolTip ToolTip1 = new ToolTip();
                    ToolTip1.ShowAlways = true;
                    if (sittingSearch != null)
                    {
                        ToolTip1.Show(ResultSitting, newLabel);
                    }
                    else { ToolTip1.Show("This sitting is Empty!", newLabel); }
                };

            }

            panel1.Controls.Add(newLabel);
        }

I get an Exception: InvalidOpearationException: There is already an open DataReader associated with this Command which must be closed first.

May you please help me solve this out?

Edit as Soner Gönül suggested:

try
        {
            string query = "SELECT * FROM [schema] WHERE idSch=@id";
            SqlCommand com = new SqlCommand(query, con);
            com.Parameters.AddWithValue("@id", idSch);
            con.Open();
            SqlDataReader read= com.ExecuteReader();

            while (precti.Read())
            {
                createLabelCmd((int)read["x"], (int)read["y"]);

            }
            con.Close();
        }
Marek
  • 3,555
  • 17
  • 74
  • 123
  • @TimSchmelter Thanks for that point. I hope it doesn`t effect the main issue with open DataReader. – Marek Oct 08 '13 at 08:11
  • I've deleted my comment since i've noticed that it indeed works to select multiple columns with `ExecuteScalar`. It seems that `SqlCommand` picks simply the first column. However, that isn't best practise at all. – Tim Schmelter Oct 08 '13 at 08:13
  • on which line you are getting the error? – Rezoan Oct 08 '13 at 08:17
  • @Rezoan `createLabelCmd((int)read["x"], (int)read["y"]);` – Marek Oct 08 '13 at 08:18

5 Answers5

2

Because when you while loop with your open SqlDataReader, there is an open connection already.

From DataReaders (ADO.NET)

“You can use the ADO.NET DataReader to retrieve a read-only, forward-only stream of data from a database.

Results are returned as the query executes, and are stored in the network buffer on the client until you request them using the Read method of the DataReader”

As a general recomendation, use using like;

using(SqlDataReader read= com.ExecuteReader())
{
    while (read.Read())
    {
       createLabelCmd((int)read["x"], (int)read["y"]);
    }
}

Or set this in your connection string;

...MultipleActiveResultSets=true;
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • I replaced the part of my code as you suggested (you can see in my edit) but still got the same Exception. May you please help me? – Marek Oct 08 '13 at 08:21
2

The cause of the problem is outlined in other answers (while a DataReader is open, the connection used by that reader cannot serve other commands), however many fails to talk about MultipleActiveResultSets that has been introduced for this kind of situations

Just change your connection string to include this option and your code will work without any change

Server=yourServer;Database=yourDB;Trusted_Connection=True;MultipleActiveResultSets=true;

To complete the answer, MARS is available starting from SQL Server 2005 and there are minor problems that you should be aware of.

Community
  • 1
  • 1
Steve
  • 213,761
  • 22
  • 232
  • 286
1

I guess you are writing a sitting planner and try to show labels at specific positions. Therefore, you would better select all records from klient table for a given event and put them in a DataSet. Then iterate through it (using a foreach) and create the labels. This way, there is only ONE command that should be sent to database and , obviously, the performance of your application will be much better.

Having said that, I don't understand how your sittingSearch variable work and I think it needs revising.

Delphi.Boy
  • 1,199
  • 4
  • 17
  • 38
1

You can either use a 2nd connection for createLabelCmd or turn on MARS (multiple active results sets) in your initial connection by adding "MultipleActiveResultSets=True" to your connection string.

http://msdn.microsoft.com/en-us/library/h32h3abf.aspx

corners
  • 151
  • 2
0

Setting MARS to True AND making sure i used ToList(); in my if statements and returns in the below code i was missing the toList() in both conditions of the if statement, i was getting the error on IIS 8.5 after publishing .. updating the statement to the below worked@!

var varM = (id == 1) ? db.M.Where(x => x.UN== userID).ToList() : db.M.Where(x => x.EUN== userID).ToList();
Vincent Cantin
  • 16,192
  • 2
  • 35
  • 57
cagedwhale
  • 51
  • 4