【问题标题】:Changes to SQLite are lost after connection.Close()在 connection.Close() 后对 SQLite 的更改丢失
【发布时间】:2010-07-30 00:07:21
【问题描述】:

在 Mac OSX 上使用 MonoTouch .NET for iPhone 和 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 建议在停止应用程序之前尝试打开一个新连接并再次从新表中选择。我在上面的代码后面加了如下代码:

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() 后丢失更改的假设是不正确的。它肯定找到了新插入的行并将其输出到控制台。但是,我停止应用程序后,表格和行仍然消失。

【问题讨论】:

  • 这是在设备模拟器中吗?您可以尝试创建一个代码命令来选择您刚刚插入的内容,而不是查看数据库吗?
  • 是的。我正在使用 monoDevelop 和 iPhone 模拟器。我一直在查看数据库,但上面的代码也尝试选择插入的内容。
  • 原来如此……没发现。
  • 有趣的是,它确实选择了插入的内容。但是一旦连接关闭,所有这些都消失了。我是 monotouch 和 sqlite 的新手,所以我确信我缺少一些简单的东西。
  • 当你运行模拟器时,你能确认它使用的数据库与你之后检查的数据库相同吗?另外,你可以关闭连接,然后以编程方式选择出来吗?

标签: c# sqlite mono xamarin.ios monodevelop


【解决方案1】:

对于处理相同问题的任何人,我想我会继续发布我的发现。我在原始帖子中描述的行为主要是设计使然。为了更清楚,这里有一个更好的解释:

当 MonoDevelop 将您的应用程序部署到 iPhone 模拟器时,您的 SQLite 数据库的副本将与它一起存在于 iPhone 环境中。因此,当您的应用程序修改数据库时,不会触及原始数据库。当您的应用程序停止时,您对数据库的模拟器副本所做的更改将丢失。但是,当应用程序运行时,您可以插入、更新、删除和选择您想要的所有内容,一切都应该按预期工作。

这仅在使用模拟器时适用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多