我试图创建一个用于数据库管理的通用 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 对象将需要它。这就是您获得无法访问已释放对象的原因。