C #: уже существует открытый DataReader, связанный с этой командой, который необходимо сначала закрыть

        String sql = "SELECT * from mybrknElements; ";
        String sql2 = "";
        String sWord = "" ;
        String sNum = "" ;
        int nWords = 0;
        cnn.Close();
        cnn.Open();
        SqlCommand command = new SqlCommand(sql, cnn);
        cnn2.Close();
        cnn2.Open();

        SqlDataReader drb;
        drb = command.ExecuteReader();
        while (drb.Read())
        {
            sNum = drb["ID"].ToString();
            sWord = drb["Element"].ToString();
            MessageBox.Show("OUTER loooop sNum = " + sNum + " sWord = " + sWord);


            sql2 = "SELECT * from mybrknElements2; ";
            String sWord2 = "" ;
            String sNum2 = "";
            SqlCommand command22 = new SqlCommand(sql2, cnn2);

            SqlDataReader drcc;
            drcc = command22.ExecuteReader(); //ERROR comes up after this line 


            while (drcc.Read())
            {
                sNum2 = drcc["ID"].ToString();
                sWord2 = drcc["Element"].ToString();
                if (Equals(sWord2,sWord2))
                {

                    nWords = nWords + 1;
                    MessageBox.Show("sNum2 = " + sNum2 + " sWord2 = " + sWord2);
                }
            }



            //---check occurances--------------


        }

Выше мой код: я использовал 2 SqlDataReaders, один в другом. Я получаю сообщение об ошибке в конце цикла while: уже существует открытый DataReader, связанный с этой командой, который должен быть сначала закрыт

Может кто-нибудь помочь? Спасибо.


person Deelliiee    schedule 11.04.2016    source источник
comment
Не связано с ошибкой, но вы имеете в виду if (Equals(sWord2,sWord2))? Я думаю, ты хочешь if (Equals(sWord1,sWord2))   -  person Michael    schedule 11.04.2016
comment
Одновременно можно открыть только 1 DataReader.   -  person Edward N    schedule 11.04.2016
comment
У вас не может быть более одного открытого устройства чтения данных на одном соединении.   -  person Zohar Peled    schedule 11.04.2016


Ответы (2)


Вам следует прекратить повторно использовать свои объекты команд и соединений и правильно избавиться от них после того, как они были использованы. Нет никаких преимуществ в повторном использовании объектов (.NET все равно будет повторно использовать открытые сокеты для базы данных через пул соединений, даже для объектов различного соединения), и это вызывает только такие проблемы.

Таким образом, без повторного использования объектов и удаления тех, которые вы правильно сделали, ваш код может закончиться примерно так:

string sql = "SELECT ID, Element FROM mybrknElements; ";
string sql2 = "SELECT ID, Element FROM mybrknElements2;";
int nWords = 0;
string connectionString = "Your Connection String";

using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sql1, connection))
{
    connection.Open();
    using (var reader = command.ExecuteReader())
    {
        string sWord = reader.GetString(0);
        string sNum = reader.GetString(1);

        using (var connection2 = new SqlConnection(connectionString))
        using (var command2 = new SqlCommand(sql2, connection2))
        {
            connection2.Open();
            using (var reader2 = command2.ExecuteReader())
            {
                string sWord2 = reader2.GetString(0);
                string sNum2 = reader2.GetString(1);

                if (Equals(sWord1,sWord2))
                {
                    nWords++;
                }
            }
        }           
    }
}

Примечание. В каждом средстве чтения данных вы используете только два столбца, поэтому я добавил эти столбцы в список выбора в каждом операторе SQL, чтобы вы не извлекали излишне данные, которые никогда не будут использоваться.

Хотя весь цикл кажется мне бессмысленным и неэффективным, если предположить, что вся его цель - получить nWords с правильным числом, вы можете сделать все это в SQL:

    SELECT  nWords = COUNT(*)
    FROM    mybrknElements AS e
            INNER JOIN mybrknElements AS e2
                ON e2.ID = e.ID;
person GarethD    schedule 11.04.2016

Попробуйте этот код,

        SqlDataReader drb;
        drb = command.ExecuteReader();
        while (drb.Read())
        {
            sNum = drb["ID"].ToString();
            sWord = drb["Element"].ToString();
            MessageBox.Show("OUTER loooop sNum = " + sNum + " sWord = " + sWord);


            sql2 = "SELECT * from mybrknElements2; ";
            String sWord2 = "" ;
            String sNum2 = "";
            SqlCommand command22 = new SqlCommand(sql2, cnn2);

            SqlDataReader drcc;
            drcc = command22.ExecuteReader(); //ERROR comes up after this line 

          drb.Close();

            while (drcc.Read())
            {
                sNum2 = drcc["ID"].ToString();
                sWord2 = drcc["Element"].ToString();
                if (Equals(sWord2,sWord2))
                {

                    nWords = nWords + 1;
                    MessageBox.Show("sNum2 = " + sNum2 + " sWord2 = " +   sWord2);
                 }
               }
            drcc.Close();
          }
person Prabhat Sinha    schedule 11.04.2016