Fazer a conexão SQLite falhar se banco de dados está faltando? (Excluído / movido)

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu tenho o seguinte método dentro class DBConnection. Eu chamo o método como este: SQLiteConnection conn = DBConnection.OpenDB(); quando eu quiser abrir uma conexão, para que eu possa executar minhas consultas. Eu posso chamar um método semelhante quando quero fechar a conexão.

O método:

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;
    }
}

Esta tudo muito bem e dandy funciona. O problema é o que try-catch. Vamos imaginar o seguinte cenário:

  • O arquivo de banco de dados tem sido movidos / excluir.

A exceção nunca será lançada. Na verdade, a primeira captura eu tropeçar em cima é quando eu executar o meu primeira consulta - onde figura que não existe tal mesa (s) e ele lança sua própria exceção. Fiquei espantado por este fenómeno estranho, mas eu logo descobri que SQLite cria um novo vazio banco de dados. Por vazio é média há tabelas , nada, apenas um arquivo de banco de dados SQLite com o mesmo nome do banco de dados antigo que deveria estar lá.

Este é um problema, eu quero o aplicativo para saber se há algo errado (banco de dados não encontrado, corrompido, sendo usado por outro processo etc.) assim que eu tento SQLiteConnection conn = DBConnection.OpenDB(); chamada.

Naturalmente, eu poderia tentar chamar um File.Exists no meu método, mas isso não parece ser uma solução adequada. Qualquer ajuda?

Foi útil?

Solução

Pelo menos em System.Data.SQLite, você pode adicionar " FailIfMissing=True " para a seqüência de conexão. SQLiteConnection.Open() irá lançar um SQLiteException se o arquivo de banco de dados não existe.

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

SQLite amostras seqüência de conexão para outro exemplo, olhar para "Desativar criar um comportamento de banco de dados".

Outras dicas

Eu não usei SQLite, mas que é um comportamento muito bizarro para auto criar um novo banco de dados.

Você pode simplesmente ajustar o seu bloco try para fazer um Select top 1 * From Table imediatamente depois de abrir a conexão, se funciona, jogar fora o resultado e continuar a devolver o objeto conn. Se ele falhar, o manipulador de exceção deve disparar.

Se você quiser detectar problemas de corrupção de banco de dados no arranque, você pode executar o comando

pragma integrity_check;

ou

pragma quick_check; (Que é mais rápido, mas menos profunda)

Este retorna uma única linha com o "ok" valor.

Caso contrário, irá reportar erros que encontrar.

Para usar o SQLite isso: Suponha que você tenha seqüência de conexão na caixa de texto 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

Eu acho que você pode easilly convertê-lo em código c #

não pegar a esse nível. Em vez disso, SQLiteConnection deve implementar IDisposable, o que significa que você deve apenas voltar a conexão aberta e permitir que o código de chamada para lidar com quaisquer excepções, bem como contar com o método Dispose para fechar a conexão.

Se não houver nenhuma maneira de mudar o comportamento SQLite padrão, então você pode ter que fazer um File.Exists. Isso seria melhor do que conectar e criar um novo arquivo, verificando para ver se é o banco de dados que você deseja, em seguida, excluir o novo arquivo no bloco catch.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top