データベース管理用の一般化されたC#コードを作成しようとしていました。これまでのところ、MSSQLとMySQLのコードは正常に動作しています。しかし、私はSQLiteのためにそれを使用しようとすると、エラーがスローされます。C#でSystem.Data.SQLite.dllを使用するデータの入力にエラーが発生しました:廃棄されたオブジェクトにアクセスできない
問題を見つけましたが、現時点でフレームワークを変更できません。私はSQLite Siteでチケットを調達して助けを求めたが、私はそれらの鶏の頭がそれをしないと言ってもメールを送らなくてもそれを削除したと思う。チケットのUUIDは2747b8a677ae2057a5617df1e20684256d6bbc93です。
エラーを再現するために、テストコードは.Net 4 Frameworkを使用してC#でVS 2010で記述されています。それは完全なプロジェクトのソースがアップロードされているWindowsフォームアプリケーションですhere。
同じコードを以下に示します:それはSQLliteのためだけに起こる理由
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();
}
}
}
あなたが把握することはできますか? 間違いがある場合は申し訳ありません。私は事前にすぐ:(
感謝を再生することができないかもしれないので、私はいくつかのネットワークの問題を持つ:)
ありがとう、私はそれを持っていますが、あなたはMSSQLとMySQLのために見ることができるように、同じコードが働いています。だから問題はSQLiteを特別なものにすることです。バグですか? – lal
実際、mssqlとmysqlでうまく動作していることに驚いています。私は、sqlコマンドをクローンしていると思っています。おそらく、プロファイラでそのオブジェクトの裏で何が起こっているのかを確認できます。それにもかかわらず、データアダプタが破棄されたときにデータアダプタが破棄されたかどうかを確認すると、期待通りの動作になることがわかります。そうであれば、dataadapterに両方のオブジェクト。 – Zalomon
私はちょうど興味深いものを見つけました。 MSSQLの場合、SQLCommandを配置した後、ガベージコレクタを使用し、別のデータアダプタの選択コマンドとして同じ配置オブジェクトを使用しました。それは動作しますが、エラーはありません。私はあなたがそれを見てみることができるプロファイラについてはあまり知らないのですか?ありがとう:) – lal