在Mac OSX上使用适用于iPhone的MonoTouch .NET和SQLite。我可以从数据库中读取没问题。但是,当我尝试对数据库进行更改时,我会遇到奇怪的行为。下面的代码毫无例外地运行,但是没有对数据库进行实际更改。我可以创建一个表,插入一条记录,选择该记录,并在控制台中显示它。但是,当我关闭数据库连接时,所有这些更改都会消失。此外,如果我在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();
如果我在SQLite浏览器中执行相同的SQL语句,它们可以正常工作:
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'}
你可以说,但值得一提的是我没有使用交易。
更新:
有趣......我可以更改上面运行SELECT查询的代码以查看'Test2'(不存在的表)并抛出SQLiteException:“没有这样的表:Test2”。
我还尝试将上述代码包装在一个事务中,因为SQLite需要进行交易...没有骰子。
更新#2:
Adam建议在停止应用程序之前尝试再次从新表中打开新连接和SELECT。我在上面的代码之后添加了以下代码:
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 :(得分:2)
对于任何处理同一问题的人,我想我会继续发表我的发现。我在原帖中描述的行为主要是设计的。更清楚的是,这是一个更好的解释:
当MonoDevelop将您的应用程序部署到iPhone模拟器时,您的SQLite数据库的COPY会随之在iPhone环境中生存。因此,当您的应用修改数据库时,不会触及原始数据库。当您的应用停止时,您对数据库的模拟器副本所做的更改将丢失。但是,当应用程序运行时,您可以插入,更新,删除和选择所需的一切,一切都应该按预期工作。
仅在使用模拟器时才这样。