Я не закрывал предыдущий DataReader, но где? - PullRequest
5 голосов
/ 02 декабря 2011

Я изменил свой предыдущий код, поэтому я не использую «использование». Он работает раньше, и код в другом классе в основном представляет одно и то же, но работает.

Я смотрю на это уже 2 часа и просто не могу понять, где могут быть проблемы.

У меня есть только один читатель, но каждый раз, когда я использую метод DisplayFileContent, я получаю сообщение об ошибке: Ошибка: There is already an open DataReader associated with this command which must be closed first.

// May be public so we can display
// content of file from different forms.
public void DisplayFileContent(string filePath)
{
    // Counting all entries.
    int countEntries = 0;

    // Encrypting/Decrypting  data.
    EncryptDecrypt security = new EncryptDecrypt();

    using (OleDbConnection connection = new OleDbConnection())
    {
        connection.ConnectionString =
            "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=" + filePath + ";" +
            "Persist Security Info=False;" +
            "Jet OLEDB:Database Password=" + 
            hashPhrase.ShortHash(storedAuth.Password) + ";";

        using (OleDbCommand command = new OleDbCommand
            ("Select * FROM PersonalData", connection))
        {
            OleDbDataReader read;

            try
            {
                // Open database connection.
                connection.Open();

                // Create a data reader.
                read = command.ExecuteReader();

                // Clearing the textbox before proceeding.
                txtDisplay.Text = string.Empty;

                // Checking if there is any data in the file.
                if (read.HasRows)
                {
                    // Reading information from the file.
                    while (read.Read())
                    {
                        // Count all entries read from the reader.
                        countEntries++;

                        // Reading all values from the file as string.
                        // While each string is encrypted, we must decrypt them.
                        // User name and password is the same as user provided
                        // while authentication.
                        txtDisplay.Text += "=== Entry ID: " + read.GetValue(0) +
                            " ===" + Environment.NewLine;
                        txtDisplay.Text += "Type: " + security.Decrypt
                            (read.GetString(1), storedAuth.Password,
                            storedAuth.UserName) + Environment.NewLine;
                        if (!read.IsDBNull(2))
                            txtDisplay.Text += "URL: " +
                                security.Decrypt(read.GetString(2),
                                storedAuth.Password, storedAuth.UserName) +
                                Environment.NewLine;
                        if (!read.IsDBNull(3))
                            txtDisplay.Text += "Software Name: " +
                                security.Decrypt(read.GetString(3),
                                storedAuth.Password, storedAuth.UserName) +
                                Environment.NewLine;
                        if (!read.IsDBNull(4))
                            txtDisplay.Text += "Serial Code: " +
                                security.Decrypt(read.GetString(4),
                                storedAuth.Password, storedAuth.UserName) +
                                Environment.NewLine;
                        if (!read.IsDBNull(5))
                            txtDisplay.Text += "User Name: " +
                                security.Decrypt(read.GetString(5),
                                storedAuth.Password, storedAuth.UserName) +
                                Environment.NewLine;
                        if (!read.IsDBNull(6))
                            txtDisplay.Text += "Password: " +
                                security.Decrypt(read.GetString(6),
                                storedAuth.Password, storedAuth.UserName) +
                                Environment.NewLine;
                        txtDisplay.Text += Environment.NewLine;
                    }
                }
                else
                {
                    txtDisplay.Text = "There is nothing to display! " +
                        "You must add something before so I can display anything here.";
                }

                // Displaying number of entries in the status bar.
                tsslStatus.Text = "A total of " + countEntries + " entries.";

                // Selecting 0 character to make sure text
                // isn't completly selected.
                txtDisplay.SelectionStart = 0;

                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }
    }
}

Ответы [ 3 ]

6 голосов
/ 02 декабря 2011

Вы вызываете command.ExecuteNonQuery непосредственно перед блоком catch. Сначала вам нужно закрыть ваш DataReader.

Я бы порекомендовал обернуть код, который использует устройство чтения данных, в блок использования:

using(OleDbDatareader read = command.ExecuteReader())
{

   ...

}

Как указано выше, command.ExecuteNonQuery () предназначен для выполнения команд, от которых вы не ожидаете возвращаемого результата. Обычно это вставки, обновления или удаления, но они могут также включать хранимые вызовы процедур, которые делают то же самое, или когда вас не волнует возвращаемый результат

3 голосов
/ 02 декабря 2011

Перед вашей линией

command.ExecuteNonQuery();

вам необходимо:

read.Close();

Кроме того, важно знать, что использование соединения НЕ закрывает его автоматически.Следовательно, перед завершением вашего соединения с использованием оператора вам необходимо

connection.Close();
1 голос
/ 02 декабря 2011

Я не вижу кода для закрытия программы чтения данных.

Добавьте наконец после улова часть:

   finally {
        if (read != null)
        {
            read.Close();
        }
}

РЕДАКТИРОВАТЬ # 1: я допустил ошибку. Вы должны закрыть ее перед выполнением следующей команды, поэтому либо удалите последнюю строку (при необходимости) перед блоком catch и добавьте блок finally, либо просто добавьте переменную read для чтения.

...