Machen Sie SQLite-Verbindung fehlschlagen, wenn Datenbank fehlt? (Gelöscht / verschoben)

StackOverflow https://stackoverflow.com/questions/807208

  •  03-07-2019
  •  | 
  •  

Frage

Ich habe die folgende Methode in class DBConnection. Ich nenne das Verfahren wie folgt aus: SQLiteConnection conn = DBConnection.OpenDB(); wenn ich will eine Verbindung öffnen, so dass ich meine Abfragen ausführen kann. Ich kann eine ähnliche Methode aufrufen, wenn ich die Verbindung schließen möchten.

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, das obwohl try-catch. Lassen Sie uns das folgende Szenario vor:

  • Die Datenbankdatei wurde verschoben / gelöscht werden.

Die Ausnahme wird nie ausgelöst. Eigentlich ist der erste Fang ich auf stolpern, wenn ich meine erste Abfrage ausführen - wo Zahlen es, dass es keine solche Tabelle (n) und es wirft seine eigene Ausnahme. Ich war von diesem seltsamen Phänomen betäubt, aber ich fand bald heraus, dass SQLite eine neue schafft leer Datenbank. Durch leer Mittelwert keine Tabellen , nichts, nur eine SQLite-Datenbank-Datei mit dem gleichen Namen wie die alten Datenbank, die angeblich dort sein.

Dies ist ein Problem, ich mag die Anwendung wissen, ob etwas nicht in Ordnung ist (Datenbank nicht gefunden wird, beschädigt, von einem anderen Prozess verwendet wird, usw.), sobald ich versuche SQLiteConnection conn = DBConnection.OpenDB(); zu nennen.

Natürlich könnte ich versuchen, ein File.Exists in meiner Methode nennen, aber das scheint nicht wie eine richtige Lösung. Jede Hilfe?

War es hilfreich?

Lösung

Mindestens in System.Data.SQLite, können Sie hinzufügen " FailIfMissing=True ", um die Verbindungszeichenfolge. SQLiteConnection.Open() ein 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 Beispiele für ein anderes Beispiel , suchen Sie nach "Deaktivieren Datenbank Verhalten erstellen".

Andere Tipps

Ich habe nicht verwendet SQLite, aber das ist ziemlich bizarres Verhalten Auto eine völlig neue Datenbank erstellen.

Sie könnten nur passen Sie Ihre try-Block eine Select top 1 * From Table sofort nach dem Öffnen der Verbindung zu tun, wenn es funktioniert, werfen das Ergebnis weg und setzen Sie Ihren conn Objekt zurückzukehren. Wenn es fehlschlägt, sollte die Exception-Handler ausgelöst.

Wenn Sie eine Beschädigung der Datenbank Probleme erkennen wollen starten, können Sie den Befehl ausführen

Pragma integrity_check;

oder

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

Das gibt eine einzelne Zeile mit dem Wert „ok“.

Sonst wird es Fehler berichtet, dass es Begegnungen.

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

     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 zu c # -Code konvertieren

Sie nicht auf dieser Ebene fangen. Stattdessen SQLiteConnection sollte IDisposable implementieren, dh Sie sollten nur die offene Verbindung zurückkehren und erlauben Code ruft alle Ausnahmen zu handhaben, sowie stützen sich auf die Dispose-Methode die Verbindung zu schließen.

Wenn es keine Möglichkeit gibt, das Standard-SQLite Verhalten zu ändern, dann könnten Sie eine File.Exists zu tun haben. Das wäre besser als Verbindungs- und Erstellen eine neue Datei, zu überprüfen, ob es die Datenbank ist Sie wollen, dann die neue Datei im catch-Block zu löschen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top