使用 System.Data.SQLite.dll在 C# 中数据填充错误:无法访问已释放的对象



我试图创建一个用于数据库管理的通用 C# 代码。到目前为止,代码在MSSQL和MySQL上运行良好。但是当我尝试将其用于SQLite时,它会抛出错误。

我想出了问题所在,但目前无法改变我的框架。我在SQLite网站上提出了一张票寻求帮助,但我认为那些鸡头甚至没有发送邮件说他们不会这样做就删除了它。机票的UUID是2747b8a677ae2057a5617df1e20684256d6bbc93。

在 VS 2010 中用 C# 编写了测试代码,并使用 .Net 4 框架来重现错误。这是一个窗口表单应用程序,完整的项目源代码在此处上传。

下面列出了相同的代码:

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

你能弄清楚为什么它只发生在SQLlite上吗?如果有任何错误,我很抱歉。而且我有一些网络问题,所以我可能无法立即重播:(

提前致谢:)

在调用 DA 之前释放 SelectCommand 对象。Fill(DT),DataAdapter 对象将需要它。这就是您获得无法访问已释放对象的原因。

最新更新