Получение ошибки при попытке вставить данные в SQLite

Я использую следующий код для обновления поля «Изображение» в моей базе данных SQLite:

    public void SetImage(byte[] image)
    {
        var sql = "UPDATE Part SET Picture=@0 WHERE PartId=" + PartId.ToString(CultureInfo.InvariantCulture);
        var con = new SQLiteConnection(GetConnectionString());

        var command = new SQLiteCommand(con)
        {
            CommandText = sql
        };

        command.Parameters.AddWithValue("@0", image);
        con.Open();
        command.ExecuteNonQuery();
        con.Close();
        command.Dispose();
        con.Dispose();
    }

Все остальные данные доступа к моей базе данных SQLite и из нее работают нормально. Просто кажется, что когда я пытаюсь вставить данные в это одно поле, мне выдает ошибку «База данных заблокирована». Мое приложение является однопоточным, и все мои другие функции доступа к данным правильно закрываются и удаляют нужные объекты. Кто-нибудь знает, что может быть не так?


person Icemanind    schedule 04.11.2012    source источник
comment
Вы одновременно открывали БД из какого-то менеджера клиентов?   -  person nawfal    schedule 05.11.2012
comment
@nawfal - Нет. Я закрыл его и даже закрыл свой антивирусный сканер и все остальное, что могло открывать файл.   -  person Icemanind    schedule 05.11.2012
comment
@icemsnind. У меня была одна и та же проблема несколько раз, и в основном, когда я обновлял свой коннектор ado.net sqlite. некоторые версии работают без суеты, а некоторые нет - не обязательно более старая версия. даже более новые версии доставляют мне эту проблему, когда старая версия работала нормально. Единственное решение, которое сработало для меня, — это размещение объектов SQLite с использованием блока using, как предлагает CL. Я бы лучше попросил вас включить вспомогательный класс, который управляет этим, чтобы вам не приходилось каждый раз использовать using и освобождать ресурсы.   -  person nawfal    schedule 06.11.2012


Ответы (1)


Ошибка «База данных заблокирована», вероятно, указывает на то, что какое-то другое соединение все еще имеет открытую транзакцию.

Убедитесь, что все команды и подключения правильно закрыты и удалены. Чтобы сделать это даже в случае исключений, используйте using.

person CL.    schedule 05.11.2012
comment
Я так тщательно просмотрел свой код, что просто не могу найти ни одного места, где соединения и команды не закрывались бы. Я признаю, что я вызываю Dispose() для объектов, а не использую блоки using, но это не должно иметь значения, верно? Кроме того, я использовал Process Monitor, чтобы попытаться выяснить, что происходит на. Я прошел через свой код, и блокировки в базе данных всегда успешны до строки command.ExecuteNonQuery();. Затем он просто терпит неудачу ... Это почти похоже на то, что SQLite исключительно блокирует себя от БД. - person Icemanind; 05.11.2012
comment
Вы можете выйти из кода с помощью таких вещей, как break, return или исключений. Поэтому вы должны всегда использовать using блоков. - person CL.; 05.11.2012
comment
Я сейчас на работе, но когда я вернусь домой, я поменяю все на using блоков и сообщу о своих выводах. - person Icemanind; 05.11.2012
comment
Все та же проблема, но я кое-что заметил. Когда я запускаю программу на своем компьютере, она терпит неудачу, однако, когда я запускаю ее на компьютере друга, она, кажется, работает. Разница между нашими машинами в том, что мой компьютер имеет четырехъядерный процессор, а его — одноядерный (хотя у него есть гиперпоточность). Возможно ли, что SQLite делает что-то с базой данных в одном ядре, а что-то делает в другом ядре? Я знаю, что моя программа не является многопоточной. Любые подсказки? - person Icemanind; 06.11.2012
comment
@icemanind, вы так уверены, что каждый запрос из вашего приложения в БД включает using или Dispose? Попробуйте тогда с using. - person nawfal; 06.11.2012
comment
@nawfal - я даже прошел через свое приложение строку за строкой, пока не дошел до строки обновления, вызывающей нарушение. Я могу убедиться, что вызывается Dispose(). Я попробую «использовать», просто чтобы посмотреть. Возможно, внутренняя ошибка в файле DLL SQLite вызывает исключение, и, возможно, использование может исправить это. - person Icemanind; 06.11.2012
comment
@nawfal - Вау, это работает, когда я перестроил весь слой данных, используя блоки «использования». Я абсолютно на 100% утилизировал каждый объект, поэтому для меня загадка, почему «использование» имеет значение, но теперь это работает! Спасибо за помощь! - person Icemanind; 06.11.2012
comment
@icemanin, приятно знать. Как я уже сказал, оберните весь using и повторяющийся код БД в один вспомогательный класс. Если бы вы сделали это один раз, вопрос о замене Dispose на using теперь сводился бы к редактированию одной строки :) - person nawfal; 06.11.2012