2016-04-26 6 views
0

Ich habe versucht, einen verallgemeinerten C# -Code für die Datenbankverwaltung erstellen. Bis jetzt funktioniert der Code gut für MSSQL und MySQL. Aber wenn ich versuche, es für SQLite zu verwenden, löst es einen Fehler aus.Verwenden von System.Data.SQLite.dll in C# Fehler beim Füllen von Daten: Kann nicht auf ein Objekt zugreifen

Ich habe das Problem herausgefunden, aber ich kann mein Framework in diesem Moment nicht ändern. Ich habe ein Ticket um SQLite Site um Hilfe gebeten, aber ich denke, dass diese Chicken Heads es gelöscht haben, ohne sogar eine Mail zu senden, die sagt, dass sie es nicht tun werden. Die UUID des Tickets ist 2747b8a677ae2057a5617df1e20684256d6bbc93.

Ein Testcode wird in VS 2010 in C# mit .Net 4 Framework geschrieben, um den Fehler neu zu erstellen. Es ist eine Windows-Formular-Anwendung, die gesamte Projektquelle wird hochgeladen here.

Der gleiche Code ist unten aufgeführt:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Data.SqlClient; 
using MySql.Data.MySqlClient; 
using System.Data.SQLite; 

namespace SQLite_Bug 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     // We assume database already exist. 
     // Need to replace **** with Appropriate values 

     string ConStr_MSSQL = @"Persist Security Info=True;User ID=sa;Password=****;Initial Catalog=master;Data Source=****"; 
     string ConStr_MySQL = @"server=localhost;userid=root;password=****;database=****"; 
     string ConStr_SQLite = @"Data Source=E:\TestDB.sqllite;Version=3;FailIfMissing=true;Max Pool Size=100;Journal Mode=Off;"; 

     private void button1_Click(object sender, EventArgs e) 
     { 
      // MSSQL Test 
      SqlConnection Con = new SqlConnection(ConStr_MSSQL); 
      Con.Open(); 
      SqlCommand SC = Con.CreateCommand(); 
      SqlDataAdapter DA = new SqlDataAdapter(); 
      DataTable DT = new DataTable(); 

      SC.CommandTimeout = 0; 
      SC.CommandType = CommandType.Text; 
      SC.Connection = Con; 
      SC.CommandText = "Select 'Test MSSQL Data'"; 

      DA.SelectCommand = SC; 
      SC.Dispose(); 

      DA.Fill(DT); 
      DA.Dispose(); 

      Con.Close(); 
      Con.Dispose(); 

      MessageBox.Show(DT.Rows[0][0].ToString()); 
      DT.Dispose(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      // MySQL Test 
      MySqlConnection Con = new MySqlConnection(ConStr_MySQL); 
      Con.Open(); 
      MySqlCommand SC = Con.CreateCommand(); 
      MySqlDataAdapter DA = new MySqlDataAdapter(); 
      DataTable DT = new DataTable(); 

      SC.CommandTimeout = 0; 
      SC.CommandType = CommandType.Text; 
      SC.Connection = Con; 
      SC.CommandText = "Select 'Test MySQL Data'"; 

      DA.SelectCommand = SC; 
      SC.Dispose(); 

      DA.Fill(DT); 
      DA.Dispose(); 

      Con.Close(); 
      Con.Dispose(); 

      MessageBox.Show(DT.Rows[0][0].ToString()); 
      DT.Dispose(); 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 
      // SQLite Test 
      //SQLiteConnection.CreateFile("E:\\TestDB.sqllite"); 
      SQLiteConnection Con = new SQLiteConnection(ConStr_SQLite); 
      Con.Open(); // <-- Throw error almost every time. unable to open database file Error. Code 14. 
      // 100% chance of getting this error if program crash before connection is closed. 
      SQLiteCommand SC = Con.CreateCommand(); 
      SQLiteDataAdapter DA = new SQLiteDataAdapter(); 
      DataTable DT = new DataTable(); 

      SC.CommandTimeout = 0; 
      SC.CommandType = CommandType.Text; 
      SC.Connection = Con; 
      SC.CommandText = "Select 'Test SQLite Data'"; 

      DA.SelectCommand = SC; 
      SC.Dispose(); // I can't move it from here. :(

      DA.Fill(DT); // <-- Throw Error. Cannot access a disposed object. Object name: 'SQLiteCommand'. 
      DA.Dispose(); 

      Con.Close(); 
      Con.Dispose(); 

      MessageBox.Show(DT.Rows[0][0].ToString()); 
      DT.Dispose(); 
     } 
    } 
} 

Können Sie herausfinden, warum es gerade für SQLlite passieren? Es tut mir leid, wenn es Fehler gibt. Und ich einige Netzwerke mit Problem so kann ich nicht in der Lage sein, richtig zu wiederholen weg :(

Vielen Dank im Voraus :)

Antwort

1

Sie Anordnen des Select Objekts vor da.Fill (DT) aufrufen, das Dataadapter-Objekt wird es brauchen. Das ist der Grund, warum Sie nicht auf das Objekt zugreifen können.

+0

Danke, ich habe das, aber wie Sie sehen können für MSSQL und MySQL der gleiche Code funktioniert (Sie beide Befehl vor dem Füllen). Die Frage ist also, was macht SQLite besonders? Ist es ein Fehler? – lal

+1

In der Tat bin ich überrascht, dass es auf mssql und mysql funktioniert, ich vermute, dass sie den sqlcommand in der Haube oder etwas klonen, vielleicht können Sie mit einem Profiler überprüfen, was hinter den Kulissen mit diesem Objekt geht. Trotzdem würde ich prüfen, ob der Datenadapter das Objekt sqlcommand entsorgt, wenn er entsorgt wird, da ich es für das erwartete Verhalten halte, und wenn das der Fall wäre, würde ich den Datenadapter die Entsorgung beider Objekte veranlassen lassen . – Zalomon

+0

Ich habe gerade etwas interessantes herausgefunden. Für MSSQL, nachdem ich den SQLCommand entsorgt hatte, benutzte ich den Garbage Collector und benutzte das gleiche entsorgte Objekt wie den Select-Befehl eines anderen Datenadapters. Es funktioniert, keine Fehler, es füllen nur die Daten !!!. Ich weiß nicht viel über Profiler können Sie einen Blick darauf werfen? Vielen Dank :) – lal

Verwandte Themen