Изменения в SQLite теряются после подключения. Close () - PullRequest
2 голосов
/ 30 июля 2010

Работа с MonoTouch .NET для iPhone и SQLite на Mac OSX.Я могу читать из базы данных без проблем.Однако, когда я пытаюсь внести изменения в базу данных, я получаю странное поведение.Приведенный ниже код работает без исключения, но в базу данных не вносятся никакие реальные изменения.Я могу создать таблицу, вставить запись, выбрать эту запись и отобразить ее в консоли.Но когда я закрываю соединение с БД, все эти изменения исчезают.Кроме того, если я поставлю точку останова в коде перед conn.Close () и проверим базу данных, таблица не существует.Похоже, я работаю только с воображаемой базой данных, которая реагирует на реальные операторы SQL.Странно.

Этот код выполняется, но фактически ничего не записывает в базу данных:

const string _connectionString = "Data Source=App_Data/MyDatabaseFile";

var conn = new SqliteConnection(_connectionString);
conn.Open();

var command = conn.CreateCommand();

command.CommandText = "CREATE TABLE Test (id integer primary key AUTOINCREMENT, text varchar(100))";
command.ExecuteNonQuery();

var cmd2 = conn.CreateCommand();
cmd2.CommandText = "INSERT INTO Test (Text) Values ('test test test')";
var rowsAffected = cmd2.ExecuteNonQuery(); //rowsAffected is 1

var cmd3 = conn.CreateCommand();
cmd3.CommandText = "SELECT * FROM Test";
var reader = cmd3.ExecuteReader();
Console.WriteLine(reader["text"]); //writes "test test test" to console, nothing in database

conn.Close();

Если я выполняю те же операторы SQL в браузере SQLite, они работают нормально:

CREATE TABLE Test (id integer primary key AUTOINCREMENT, text varchar(100));
INSERT INTO Test (Text) Values ('test test test');
SELECT * FROM Test;

... yields {id = 1, text = 'test test test'}

Вы можете сказать, но стоит упомянуть, что я не использую транзакции.

ОБНОВЛЕНИЕ:

Интересно ... Я могу изменить приведенный выше код, который запускает запрос SELECT, чтобы посмотреть в 'Test2' (несуществующая таблица), и он выдает исключение SQLiteException: "Нет такой таблицы: Test2".

Я также пытался обернуть вышеупомянутый код в транзакцию, когда не было шансов, что SQLite требует транзакций ... без кубиков.

ОБНОВЛЕНИЕ № 2:

Адам предложил попытатьсяоткройте новое соединение и снова ВЫБЕРИТЕ из новой таблицы перед остановкой приложения.Я добавил следующий код после кода выше:

var conn2 = new SqliteConnection(_connectionString);
conn2.Open();
var cmd4 = conn2.CreateCommand();
cmd4.CommandText = "SELECT * FROM Test";
var reader2 = cmd4.ExecuteReader();
Console.WriteLine("2nd attempt: " + reader2["text"]); //outputs correctly
conn.Close();

Хорошо, поэтому мое предположение о потере изменений после подключения. Close () неверно.Он определенно нашел новую вставленную строку и вывел ее на консоль.Однако таблица и строка по-прежнему исчезают после остановки приложения.

1 Ответ

2 голосов
/ 01 августа 2010

Для тех, кто имеет дело с тем же вопросом, я решил пойти дальше и опубликовать свои выводы. Поведение, которое я описал в своем первоначальном посте, в основном носит дизайнерский характер. Чтобы быть более понятным, вот лучшее объяснение:

Когда MonoDevelop развертывает ваше приложение на iPhone Simulator, КОПИЯ вашей базы данных SQLite уходит вместе с ней, чтобы жить в среде iPhone. Поэтому, когда ваше приложение изменяет вашу базу данных, исходная база данных не затрагивается. Когда ваше приложение останавливается, изменения, внесенные в копию базы данных симулятора, теряются. Однако, пока приложение работает, вы можете вставлять, обновлять, удалять и выбирать все, что вы хотите, и все должно работать как положено.

Это верно только при использовании симулятора.

...