MonoTouch& SQLite - 以前成功连接后无法打开数据库

时间:2012-10-14 15:15:21

标签: c# ios sqlite xamarin.ios

我很难从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();

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

3 个答案:

答案 0 :(得分: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();
}

这样可以确保自动 finally子句将处理您创建的实例。

您也可以考虑重用您的(第一个)连接实例,例如:打开它一次,并在您的应用程序中的任何地方重复使用它。在这种情况下,您需要注意线程(默认情况下,您可以更改它,每个连接只能在创建它的线程上使用)。

重用可以帮助您的应用程序性能,但它也无法真正解决您的问题(但它可能会隐藏它)。所以我建议你先尝试调试一下:

使用MonoDevelop,您可以在/Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs文件(包含在MonoTouch安装中)上的第136行设置断点,以查看实际的n错误代码(在它转换为字符串之前) )。

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

答案 1 :(得分:1)

我建议使用“使用”块。这将确保所有内容都正确处理掉,并且当它已经关闭时你没有关闭连接..

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

}

答案 2 :(得分:0)

好的 - 我现在通过移动关闭并将其处理成“最终”来实现它。

var mySqlConn = new SqliteConnection (GlobalVars.connectionString);

mySqlConn.Open ();

try {

// CODE HERE

} finally {

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

}