c# 数据库连接中的 ObjectDisposedException class
ObjectDisposedException in c# database connection class
我是 C# 的新手,我正在用 C# 编写一个需要连接 sqlite 数据库的应用程序。我认为创建自己的 DBConnection
class 对我来说最简单,我在下面给出了它。我目前遇到的主要问题是析构函数。有时当我实例化这个 class 并且它超出范围时,我得到一个
System.ObjectDisposedException; 'Cannot access a disposed object.
Object name: 'SQLiteConnection'.'
现在我已经搜索了这是什么意思的定义,但我不是很明白。
对象正在实例化为 wpf 应用程序的一部分 window,一旦 window 被 x'd 和数据库操作完成后,就会抛出此异常。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Data.SQLite;
using System.IO;
namespace PhotoSuppliesInc
{
//this class will be used for connecting to the database in the various forms
public class DBConnector
{
//----------------------------------PRIVATES------------------------------//
//this is the connection to the db
private SQLiteConnection dbConnection;
//-------------------CONSTRUCTOR(S) and DESCTRUCTOR----------------//
public DBConnector()
{
string connectionString = "Data Source=C:\Users\dmand\source\repos\PhotoSuppliesInc\PhotoSuppliesInc\database\riverfrontphoto.db;" +
"Version = 3; FailIfMissing=True; Foreign Keys=True;";
try
{
dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
MessageBox.Show("Database connected successfully");
}//end try
catch (SQLiteException e) { MessageBox.Show("error opening database"); }
}//end constructor
//destructor removes connection to database
~DBConnector()
{
dbConnection.Close();
}
//--------------------------------------------------GETTER(S)------------------------//
//public string Get_Filepath() { return filepath; }
//--------------------------------------------------UTILITY FUNCTIONS----------------//
public List<string> Select_Query(string query_string, string columns)
{
//the names of the columns in the select statement
string[] selection_columns = columns.Split();
//each member of the array is the tuple, the data is separated by spaces
List<string> result = new List<string>();
//this string constructs the result line to be inserted into the result list
string tempstring;
SQLiteCommand command = new SQLiteCommand(query_string, dbConnection);
SQLiteDataReader reader = command.ExecuteReader();
while (reader.Read())
{
tempstring = "";//reset the temp string for each tuple
int i = 0;
foreach(string s in selection_columns)
{
tempstring += reader[s] + " ";
i++;
}
//I'm not sure why result.add must go here, but it does
result.Add(tempstring);
}
//the result is a list who's contents are strings that represent each tuple
return result;
}
}//end class
}//end namespace
///////in LoginWindow.xaml.cs////
这就是我在 window 代码文件中使用 class 的方式。
...
public LoginWindow()
{
itializeComponent();
//testing the DBConnector class:
DBConnector riverfront = new DBConnector();
string output_string = "";
foreach (string s in riverfront.Select_Query(@"select distinct fname || ' ' || lname as 'Full_Name', country from employee, employee_account limit 5", "Full_Name country"))
output_string += s + "\n";
MessageBox.Show(output_string);
}
...
正如我所说,我不知道这个错误是什么意思,或者我是否正确地使用了这种语言的析构函数。在我看来,这里应该没有问题。有人可以帮我弄清楚这个错误在我的 class 中意味着什么吗?
谢谢大家的宝贵时间。
您没有正确使用 "destructors",因为 C# 没有 析构函数,它有 终结器。
做你想做的事情的正确方法是在 using
块中实现 IDisposable
pattern 和访问你的 class 的实例。
Finalizers(用 ~ 语法表示)是不确定的——您无法控制垃圾收集器何时运行终结器,或者它是否运行过。在 using 块中实施 IDisposable
和访问实例允许您实施资源的确定性清理。
这就是你得到 ObjectDisposedException
的原因:你的 class 的终结器是 运行 在 你的 SQLiteConnection
被处置。
我是 C# 的新手,我正在用 C# 编写一个需要连接 sqlite 数据库的应用程序。我认为创建自己的 DBConnection
class 对我来说最简单,我在下面给出了它。我目前遇到的主要问题是析构函数。有时当我实例化这个 class 并且它超出范围时,我得到一个
System.ObjectDisposedException; 'Cannot access a disposed object. Object name: 'SQLiteConnection'.'
现在我已经搜索了这是什么意思的定义,但我不是很明白。
对象正在实例化为 wpf 应用程序的一部分 window,一旦 window 被 x'd 和数据库操作完成后,就会抛出此异常。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Data.SQLite;
using System.IO;
namespace PhotoSuppliesInc
{
//this class will be used for connecting to the database in the various forms
public class DBConnector
{
//----------------------------------PRIVATES------------------------------//
//this is the connection to the db
private SQLiteConnection dbConnection;
//-------------------CONSTRUCTOR(S) and DESCTRUCTOR----------------//
public DBConnector()
{
string connectionString = "Data Source=C:\Users\dmand\source\repos\PhotoSuppliesInc\PhotoSuppliesInc\database\riverfrontphoto.db;" +
"Version = 3; FailIfMissing=True; Foreign Keys=True;";
try
{
dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
MessageBox.Show("Database connected successfully");
}//end try
catch (SQLiteException e) { MessageBox.Show("error opening database"); }
}//end constructor
//destructor removes connection to database
~DBConnector()
{
dbConnection.Close();
}
//--------------------------------------------------GETTER(S)------------------------//
//public string Get_Filepath() { return filepath; }
//--------------------------------------------------UTILITY FUNCTIONS----------------//
public List<string> Select_Query(string query_string, string columns)
{
//the names of the columns in the select statement
string[] selection_columns = columns.Split();
//each member of the array is the tuple, the data is separated by spaces
List<string> result = new List<string>();
//this string constructs the result line to be inserted into the result list
string tempstring;
SQLiteCommand command = new SQLiteCommand(query_string, dbConnection);
SQLiteDataReader reader = command.ExecuteReader();
while (reader.Read())
{
tempstring = "";//reset the temp string for each tuple
int i = 0;
foreach(string s in selection_columns)
{
tempstring += reader[s] + " ";
i++;
}
//I'm not sure why result.add must go here, but it does
result.Add(tempstring);
}
//the result is a list who's contents are strings that represent each tuple
return result;
}
}//end class
}//end namespace
///////in LoginWindow.xaml.cs////
这就是我在 window 代码文件中使用 class 的方式。 ...
public LoginWindow()
{
itializeComponent();
//testing the DBConnector class:
DBConnector riverfront = new DBConnector();
string output_string = "";
foreach (string s in riverfront.Select_Query(@"select distinct fname || ' ' || lname as 'Full_Name', country from employee, employee_account limit 5", "Full_Name country"))
output_string += s + "\n";
MessageBox.Show(output_string);
}
...
正如我所说,我不知道这个错误是什么意思,或者我是否正确地使用了这种语言的析构函数。在我看来,这里应该没有问题。有人可以帮我弄清楚这个错误在我的 class 中意味着什么吗? 谢谢大家的宝贵时间。
您没有正确使用 "destructors",因为 C# 没有 析构函数,它有 终结器。
做你想做的事情的正确方法是在 using
块中实现 IDisposable
pattern 和访问你的 class 的实例。
Finalizers(用 ~ 语法表示)是不确定的——您无法控制垃圾收集器何时运行终结器,或者它是否运行过。在 using 块中实施 IDisposable
和访问实例允许您实施资源的确定性清理。
这就是你得到 ObjectDisposedException
的原因:你的 class 的终结器是 运行 在 你的 SQLiteConnection
被处置。