2010-07-30 1 views
2

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

Этот код работает, но на самом деле не писать ничего в базе данных:

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; 

... дает {id = 1, text = 'test test test}}

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

UPDATE:

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

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

UPDATE # 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(); 

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

+0

Это внутри эмулятора устройства? Вместо того, чтобы смотреть на базу данных, можете ли вы попытаться создать команду кода, чтобы выбрать, что вы только что вставили? –

+0

Да. Я использую monoDevelop и симулятор iPhone. Я смотрел базу данных, но приведенный выше код также пытается выбрать, что было вставлено. –

+0

Так оно и не ... не заметил. –

ответ

2

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

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

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