2012-10-14 48 views
2

我很难从MonoTouch的SQLite数据库中读取数据。MonoTouch&SQLite - 先前成功连接后无法打开数据库

我可以读取并没有在最初的几个屏幕任何困难写,然后突然我无法创建一个错误的任何进一步的连接:

Mono.Data.Sqlite.SqliteException: Unable to open the database file 
at Mono.Data.Sqlite.SQLite3.Open (System.String strFilename, SQLiteOpenFlagsEnum flags, Int32 maxPoolSize, Boolean usePool) [0x0007e] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs:136  
at Mono.Data.Sqlite.SqliteConnection.Open() [0x002aa] in /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnection.cs:888 

我保证我处理每一次关闭所有的连接我使用它,但仍然有这个问题。例如:

var mySqlConn = new SqliteConnection(GlobalVars.connectionString); 
mySqlConn.Open(); 
SqliteCommand mySqlCommand = new SqliteCommand(SQL, mySqlConn); 
mySqlCommand.ExecuteNonQuery(); 
mySqlConn.Close(); 
mySqlCommand.Dispose(); 
mySqlConn.Dispose(); 

我在猜测我没有正确关闭连接。任何帮助将不胜感激。

回答

2

我很确定你的猜测是正确的。但是很难猜测出了什么问题(例如,connectionString中定义的内容会影响Sqlite初始化和工作的方式)。

从你的例子中你似乎正确地配置SqliteConnection但事情可能仍然出错。例如。如果某些代码引发异常(并且您在某处捕获它),则可能永远不会调用Dispose调用。这将是更安全的做一些事情,如:

using (var mySqlConn = new SqliteConnection(GlobalVars.connectionString) { 
    mySqlConn.Open(); 
    using (SqliteCommand mySqlCommand = new SqliteCommand(SQL, mySqlConn)) { 
     mySqlCommand.ExecuteNonQuery(); 
     // work with the data 
    } 
    mySqlConn.Close(); 
} 

这将确保自动地最终条款将部署创建实例。

另外,您可能要考虑重新使用您的(第一个)连接实例,例如打开一次,然后在应用程序的任何地方重新使用它。在这种情况下,OTOH你需要知道线程(默认情况下,你可以改变它,每个连接只能在创建它的线程上使用)。

重复使用可以帮助您的应用程序的性能,但它也不能真正解决您的问题(但它可能会隐藏它)。因此,我建议你尝试调试这个第一:

使用MonoDevelop的,你可以设置在/Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs文件行#136(它是包含在你的MonoTouch的安装)断点,看看实际的n错误代码(它被翻译前到一个字符串)。

您还可以在dispose代码上设置断点以确保它被执行(并且不会返回错误)。连接创建和处理的数量应该匹配。如果不是,则使用呼叫堆栈来查看谁没有关闭而打开。

+0

没错 - 我没有想到这个处置在捕捉期间没有开火。我会再看看我用过的代码。你的方法听起来更健壮。 –

1

我建议使用“使用” block..That会确保一切正常,并处理掉,你是不关闭连接时,它已关闭..

using (SqliteConnection conn = new SqliteConnection(GlobalVars.connectionString)) 
{ 
      conn.Open(); 
      SqliteCommand command = new SqliteCommand (conn); 
          ............. 

} 
+0

感谢您的提示。我会检查一下。我设法通过try/finally来正确地工作。最后关闭和处置的地方。 –

+0

当然!关于“使用”的好处之一是,它会自动为您提供尝试,抓取并最终(调用关闭和处置..)。[链接] http://www.w3enterprises.com/articles/using。 aspx –

0

OK - 我现在通过移动关闭并将其部署到“最终”来实现它的工作。

var mySqlConn = new SqliteConnection (GlobalVars.connectionString); 

mySqlConn.Open(); 

try { 

// CODE HERE 

} finally { 

    mySqlConn.Close(); 
    mySqlConn.Dispose(); 

} 
+0

这正是使用()所做的。但是,而不是try-catch-finally,它更容易阅读。 – Kai