2009-04-30 16 views
5

Tengo el siguiente método dentro de class DBConnection. Llamo al método de esta manera: SQLiteConnection conn = DBConnection.OpenDB(); cuando quiero abrir una conexión, para poder ejecutar mis consultas. Puedo llamar a un método similar cuando quiero cerrar la conexión.¿Ha fallado la conexión SQLite si falta la base de datos? (eliminado/movido)

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

Todo esto funciona bien y dandy. El problema es el try-catch sin embargo. Imaginemos el siguiente escenario:

  • El archivo de la base de datos ha sido movido/eliminar.

La excepción nunca se arrojará. En realidad, la primera trampa que encuentro es cuando ejecuto mi primera consulta, donde se da el caso de que no existe tal tabla (s) y arroja su propia excepción. Me sorprendió este extraño fenómeno, pero pronto descubrí que SQLite crea una nueva base de datos vacía . Por vacío significa sin tablas, nada, solo un archivo de base de datos SQLite con el mismo nombre que la antigua base de datos que se suponía que estaba allí.

Esto es un problema, quiero que la aplicación sepa si hay algún problema (base de datos no encontrada, dañado, usado por otro proceso, etc.) tan pronto como intento llamar al SQLiteConnection conn = DBConnection.OpenDB();.

Naturalmente, podría intentar llamar a un archivo. Existe en mi método, pero eso no parece una solución adecuada. ¿Alguna ayuda?

Respuesta

17

Al menos en System.Data.SQLite, puede agregar "FailIfMissing=True" a su cadena de conexión. SQLiteConnection.Open() lanzará un SQLiteException si el archivo de base de datos no existe.

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

Ver SQLite Connection String Samples para otro ejemplo, busque "Desactivar crear el comportamiento de base de datos".

2

No he usado SQLite, pero ese es un comportamiento bastante extraño para crear automáticamente una base de datos completamente nueva.

Puede ajustar su bloque try para hacer un Select top 1 * From Table inmediatamente después de abrir la conexión, si funciona, deseche el resultado y continúe devolviendo su objeto conn. Si falla, el manejador de excepciones debería disparar.

+1

Sí, pensé que era así! Pero no parece ser únicamente System.Data.SQLite que hace esto. Sé que los servidores web SQLite usan lo mismo. Además, también he pensado en la idea de la consulta SQL, pero parece un desperdicio. Definitivamente marcaré su respuesta como la respuesta aceptada, si no hay una forma "adecuada" de hacerlo. – CasperT

-2

Si no hay forma de cambiar el comportamiento predeterminado de SQLite, entonces puede que tenga que hacer un File.Exists. Eso sería mejor que conectar y crear un nuevo archivo, verificar si es la base de datos que desea, y luego eliminar el nuevo archivo en el bloque catch.

-1

No captar en ese nivel. En su lugar, SQLiteConnection debe implementar IDisposable, lo que significa que debe devolver la conexión abierta y permitir que el código de llamada maneje las excepciones, así como confiar en el método Dispose para cerrar la conexión.

1

Si desea detectar problemas de corrupción de base de datos en la puesta en marcha, se puede ejecutar el comando

INTEGRITY_CHECK pragma;

o

pragma quick_check; (que es más rápido, pero menos minucioso)

Esto devuelve una sola fila con el valor "ok".

De lo contrario, informará los errores que encuentre.

0

Para uso sqlite esto: Supongamos que tenemos cadena de conexión en el cuadro 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 

Creo que se puede convertir facilmente en C# código

Cuestiones relacionadas