2012-10-14 86 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