2009-04-30 5 views
5

Ich habe die folgende Methode innerhalb class DBConnection. Ich rufe die Methode so auf: SQLiteConnection conn = DBConnection.OpenDB(); wenn ich eine Verbindung öffnen möchte, damit ich meine Abfragen ausführen kann. Ich kann eine ähnliche Methode aufrufen, wenn ich die Verbindung schließen möchte.SQLite-Verbindung fehlschlagen, wenn Datenbank fehlt? (gelöscht/verschoben)

Die Methode:

public static SQLiteConnection OpenDB() 
{ 
    try 
    { 
     //Gets connectionstring from app.config 
     string myConnectString = 
      ConfigurationManager.ConnectionStrings[ 
       "LegMedSQLLite.Properties.Settings.LegMedSQLLiteDBConnectionString"].ConnectionString; 

     var conn = new SQLiteConnection(myConnectString); 

     conn.Open(); 
     return conn; 
    } 
    catch (SQLiteException e) 
    { 
     MessageBox.Show(e.ToString(), "TEST"); 
     return null; 
    } 
} 

Das alles funktioniert gut und schön. Das Problem ist jedoch der Versuch zu fangen. Stellen wir uns das folgende Szenario vor:

  • Die Datenbankdatei wurde verschoben/löschen.

Die Ausnahme wird niemals ausgelöst. Der erste Haken, auf den ich stoße, ist der, wenn ich meine erste Abfrage ausfühle - wo sie feststellt, dass es keine solchen Tabellen gibt und sie ihre eigene Ausnahme auslöst. Ich war von diesem seltsamen Phänomen betäubt, aber ich fand bald heraus, dass SQLite eine neue leere Datenbank erstellt. Mit leer ist meine keine Tabellen, nichts, nur eine SQLite-Datenbank-Datei mit dem gleichen Namen wie die alte Datenbank, die da sein sollte.

Dies ist ein Problem, ich möchte die Anwendung wissen, wenn etwas falsch ist (Datenbank nicht gefunden, beschädigt, durch einen anderen Prozess usw. verwendet), sobald ich versuche, SQLiteConnection conn = DBConnection.OpenDB(); aufrufen.

Natürlich könnte ich versuchen, eine Datei.Exists in meiner Methode aufrufen, aber das scheint nicht eine richtige Lösung. Irgendeine Hilfe?

Antwort

17

Zumindest in System.Data.SQLite können Sie Ihrer Verbindungszeichenfolge "FailIfMissing=True" hinzufügen. SQLiteConnection.Open() wird eine SQLiteException werfen, wenn die Datenbankdatei nicht existiert.

string ConnectString = "Data Source=file.sdb; FailIfMissing=True"; 
DbConnection db = new SQLiteConnection(ConnectString); 
db.Open(); // Fails if file.sdb does not exist 

Siehe SQLite Connection String Samples für ein anderes Beispiel, suchen Sie nach „Deaktivieren Datenbank Verhalten erstellen“.

2

Ich habe nicht SQLite verwendet, aber das ist ziemlich bizarr Verhalten, um automatisch eine brandneue Datenbank zu erstellen.

Sie können Ihren try-Block einfach so anpassen, dass er sofort nach dem Öffnen der Verbindung eine Select top 1 * From Table ausführt. Wenn es funktioniert, werfen Sie das Ergebnis weg und geben Sie weiterhin Ihr conn Objekt zurück. Wenn dies fehlschlägt, sollte der Ausnahmebehandler ausgelöst werden.

+1

Ja, ich dachte, dass es so gut war! Aber es scheint nicht nur System.Data.SQLite, die dies tut. Ich weiß, dass der SQLite-Webserver dasselbe tut. Ich habe auch an die SQL-Abfrage Idee gedacht, aber es scheint nur so eine Verschwendung. Ich werde Ihre Antwort definitiv als akzeptierte Antwort bezeichnen, wenn es keinen "richtigen" Weg gibt, dies zu tun. – CasperT

-2

Wenn es keine Möglichkeit gibt, das SQLite-Standardverhalten zu ändern, müssen Sie möglicherweise File.Exists ausführen. Das wäre besser, als eine neue Datei zu verbinden und zu erstellen, zu prüfen, ob es die gewünschte Datenbank ist, und dann die neue Datei im Catch-Block zu löschen.

-1

Nicht auf dieser Ebene fangen. Stattdessen sollte SQLiteConnection IDisposable implementieren, was bedeutet, dass Sie einfach die geöffnete Verbindung zurückgeben und zulassen, dass der aufrufende Code alle Ausnahmen behandeln sollte, und sich auf die Dispose-Methode verlassen können, um die Verbindung zu schließen.

1

Wenn Sie Datenbank Korruption Probleme erkennen wollen starten, können Sie den Befehl

Pragma integrity_check auszuführen;

oder

pragma quick_check; (Das ist schneller, aber weniger gründlich)

Dies gibt eine einzelne Zeile mit dem Wert "OK" zurück.

Andernfalls meldet es Fehler, die es auftritt.

0

für SQLite verwenden diese: Angenommen, Sie Verbindungszeichenfolge in Text haben txtConnSqlite

 Using conn As New System.Data.SQLite.SQLiteConnection(txtConnSqlite.Text) 
      Dim FirstIndex As Int32 = txtConnSqlite.Text.IndexOf("Data Source=") 
      If FirstIndex = -1 Then MsgBox("ConnectionString is incorrect", MsgBoxStyle.Exclamation, "Sqlite") : Exit Sub 
      Dim SecondIndex As Int32 = txtConnSqlite.Text.IndexOf("Version=") 
      If SecondIndex = -1 Then MsgBox("ConnectionString is incorrect", MsgBoxStyle.Exclamation, "Sqlite") : Exit Sub 
      Dim FilePath As String = txtConnSqlite.Text.Substring(FirstIndex + 12, SecondIndex - FirstIndex - 13) 
      If Not IO.File.Exists(FilePath) Then MsgBox("Database file not found", MsgBoxStyle.Exclamation, "Sqlite") : Exit Sub 
      Try 
       conn.Open() 
       Dim cmd As New System.Data.SQLite.SQLiteCommand("SELECT * FROM sqlite_master WHERE type='table';", conn) 
       Dim reader As System.Data.SQLite.SQLiteDataReader 
       cmd.ExecuteReader() 
       MsgBox("Success", MsgBoxStyle.Information, "Sqlite") 
      Catch ex As Exception 
       MsgBox("Connection fail", MsgBoxStyle.Exclamation, "Sqlite") 
      End Try 
     End Using 

Ich glaube, Sie easilly es Code in C# konvertieren

Verwandte Themen