C # и SQL Server: выборка данных, а затем удаление возвращает ошибку

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

public void checkDB()
{
    string query = "SELECT * FROM dbt";

    SqlCommand sqlCommand = new SqlCommand(query, conn);

    SqlDataReader reader;
    int id = -1;

    using (reader = sqlCommand.ExecuteReader())
    {
            if (reader.Read())
            {
                String data= reader["sdata"].ToString();
                Order o = new Order(reader["sdata"].ToString());
                o.prepareForScript();
                id = reader.GetSqlInt32(1).Value;
            }

            reader.Close();
    }

    if (id != -1)
    {
        string removeQuery = "DELETE FROM data WHERE ID=" + id;

        SqlCommand removeCMD = new SqlCommand(removeQuery, conn);

        removeCMD.ExecuteNonQuery();
    }
}

Этот код приводит к исключению

необработанное исключение типа System.InvalidOperationException произошло в System.Data.dll

с дополнительной информацией о том, что читатель уже связан с этим подключением. Однако, как вы можете видеть, считыватель одновременно закрыт и находится внутри цикла использования, что означает, что он определенно должен быть закрыт. Кто-нибудь знает, как это исправить?


person Thijser    schedule 05.08.2015    source источник
comment
stackoverflow.com/questions/5440168/   -  person splattne    schedule 05.08.2015
comment
Попробуйте обернуть свои команды SQL в using. см. stackoverflow.com/questions/16985876/   -  person Mark    schedule 05.08.2015
comment
Может быть conn проблема. Вы пытались закрыть соединение после запроса SELECT и открыть для запроса DELETE.   -  person Harshit    schedule 05.08.2015
comment
SQL Injection alert - вам следует не объединяйте вместе ваши операторы SQL - вместо этого используйте параметризованные запросы, чтобы избежать внедрения SQL   -  person marc_s    schedule 05.08.2015
comment
@Marc_s Я знаю о риске, однако я беру int из базы данных, а затем отправляю его обратно для удаления, что не должно быть здесь риска, верно?   -  person Thijser    schedule 05.08.2015
comment
Также обратите внимание на ключевое слово OUTPUT. Вы можете удалить и вернуть все удаленные строки одновременно.   -  person Mark    schedule 05.08.2015
comment
@Thijser: просто заведите привычку делать это правильно! Не делайте этого с параметрами один раз и без другого - просто используйте параметризованные запросы всегда на всякий случай!   -  person marc_s    schedule 05.08.2015
comment
@Thijser: посмотри, что Джон Скит говорит по этой теме - и принимает его слова близко к сердцу!   -  person marc_s    schedule 05.08.2015


Ответы (1)


Вам необходимо сначала утилизировать SqlCommand, как показано ниже:

using (SqlCommand sqlCommand = new SqlCommand(query, conn))
{
        SqlDataReader reader;
        int id = -1;

        using (reader = sqlCommand.ExecuteReader())
        {
            if (reader.Read())
            {


                String data= reader["sdata"].ToString();
                Order o = new Order(reader["sdata"].ToString());
                o.prepareForScript();
                id = reader.GetSqlInt32(1).Value;
            }
            reader.Close();
        }
}

Or

включить MultipleActiveResultSets. Таким образом, SQL Server позволяет использовать несколько считывателей открытых данных на одном соединении.

Но я бы посоветовал не использовать ваши операторы SQL вместе, чтобы избежать Sql Injection.

person Neel    schedule 05.08.2015
comment
рад, что помог @Thijser - person Neel; 05.08.2015