2016-07-05 3 views
2

У меня проблема с моим кодом. Я хочу удалить несколько строк в моей базе данных SQLite, но я получаю исключение «База данных заблокировано». Я прочитал несколько сообщений об этом, например this post, но моя проблема все еще здесь.«База данных заблокирована» с SQLite и C#

Вот мой код:

using (var c = new SQLiteConnection(_connectionSQLite)) 
{ 
    c.Open(); 

    if (c.State == ConnectionState.Open) 
    { 
     var reqExist = string.Concat("SELECT id FROM ... "); 
     using (var cmdExist = new SQLiteCommand(reqExist, c)) 
     { 
      var reqUpdate = string.Concat("UPDATE ... WHERE id = ", cmdExist.ExecuteScalar()); 

      using (var cmdUpdate = new SQLiteCommand(reqUpdate, c)) 
      { 
       cmdUpdate.ExecuteNonQuery(); 
      } 
     } 
    } 

    c.Close(); 
} 

я получаю «база данных заблокирована» исключение на линии cmdUpdate.ExecuteNonQuery();. Я попробовал заменить DELETE FROM, тот же результат, но с SELECT, он работает, я действительно не понимаю, что не так с моим кодом.

Спасибо за любую помощь.

+3

@AbhilashRVankayala - Это ужасный совет. Нет ничего плохого в вложенных операциях using, и такие утверждения (или equiv try-finallys) необходимы для обеспечения правильного удаления ресурсов, что является одной из причин их проблемы. – antiduh

+0

Вы открываете несколько соединений с одной и той же базой данных одновременно? –

+0

Неприятные вещи произойдут, если ExecuteScalar не найдет никакого идентификатора. Кажется умной идеей конкат возвратить ExecuteScalar, но .... – Steve

ответ

1

Вы пытаетесь запустить вторую команду до того, как выбрали первую. cmdExist, вероятно, заблокирует базу данных при попытке запустить cmdUdpdate.

Вы должны реорганизовать свой код, чтобы блоки using для ваших команд не были вложены.

Does SQLite lock the database file on reads?, похоже, предполагает, что вы сможете читать, а затем писать, поэтому я также должен убедиться, что у вас нет базы данных, открытой из другого места. Тем не менее, он все еще кажется вероятным виновником.

+0

Я отделяю каждый запрос, но у меня все еще есть проблема, даже с удалением после каждой команды. – BlackAlpha

+0

Спасибо за этот ответ, я вложил блокировку для своих команд, и это сводило меня с ума, и ваш ответ помог. – Brcinho

0

Попробуйте упростить ваш выбор обновит в одного заявления, как это:

UPDATE ... WHERE ID = (SELECT ID FROM ...)

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

Если этот комбинированный оператор выходит из строя из-за заблокированной базы данных, то вы знаете, что что-то еще блокирует обновление, а не выбор. В приложении есть что-то еще, что приводит к сбою блокировки базы данных.

4

ОК, спасибо за помощь. Мне просто нужно .dispose() два считывателя в другой функции перед вставкой/обновлением, и это работает!

Смежные вопросы