2012-10-14 3 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에서는이 경우 스레딩을 인식해야합니다 (기본적으로 변경할 수 있으며 각 연결은 스레드를 만든 스레드에서만 사용하는 것이 안전합니다).

재사용하면 앱 성능에 도움이되지만 실제로 문제가 해결되지는 않지만 숨길 수 있습니다. 그래서 난 당신이 디버깅하려고 제안이 첫 번째 :이 번역되기 전에 당신이 (실제 n 오류 코드를 확인합니다 (MonoTouch 설치에 포함 됨) /Developer/MonoTouch/Source/mono/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs 파일에 라인 번호 (136)에 중단 점을 설정할 수 있습니다 MonoDevelop을 사용하여

문자열로).

dispose 코드에 중단 점을 설정하여 코드가 실행되도록하고 오류를 반환하지 않을 수도 있습니다. 연결 만들기 및 삭제 횟수가 일치해야합니다. 그렇지 않은 경우 콜 스택을 사용하여 누가 개업하지 않고 개업하는지 확인하십시오.

+0

맞아요. 나는 잡을 때 발사하지 말라고 생각하지 않았습니다. 내가 사용한 코드를 다시 살펴 보겠습니다. 귀하의 방법은 더욱 강력하게 들립니다. –

1
나는 block..That이 모든 것이 제대로도 떨어져 배치되어 있는지 확인합니다 "사용"을 사용하여 제안

이미 닫혀있을 때 당신이 ...

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

} 
+0

팁 주셔서 감사합니다. 나는 이것을 조사 할 것이다. try/finally를 사용하여 제대로 작동하도록했습니다. 마침내 닫고 처분하는 곳. –

+0

확실! "사용하다"에 대한 좋은 점 중 하나는 자동으로 시도하고 잡아서 (가까이에 전화하여 처분 ..)하는 것입니다. [link] http://www.w3enterprises.com/articles/using. aspx –

0

확인을 연결을 종료되지 않습니다 - 내가 이제는 닫기를 이동하고 "마침내"로 처리하여 작동하게되었습니다.

var mySqlConn = new SqliteConnection (GlobalVars.connectionString); 

mySqlConn.Open(); 

try { 

// CODE HERE 

} finally { 

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

} 
+0

이것은 using()이하는 것과 정확히 같습니다.그러나 try-catch-finally 대신에 읽기가 더 쉽습니다. – Kai

관련 문제