使用 1.0.82.0 版附带的设计器生成的数据集/表适配器时,我遇到了同样的问题System.Data.Sqlite.dll
——关闭连接后,我们无法使用System.IO.FileStream
. 我正确配置了连接和表格适配器,并且没有使用连接池。
根据我的第一次搜索(例如this和this thread),库本身似乎存在问题——对象未正确释放和/或池问题(我不使用)。
在阅读了您的问题后,我尝试仅使用 SQLiteCommand 对象来复制问题,我发现当您不处理它们时会出现问题。2012-11-27 19:37 UTC 更新:System.Data.SQLite 的这张票进一步证实了这一点,其中开发人员解释说“与连接关联的所有SQLiteCommand 和 SQLiteDataReader 对象[应该]正确处理”。
然后我打开生成的 TableAdapters,我看到没有实现该Dispose
方法——所以实际上创建的命令没有被释放。我实现了它,负责处理所有命令,我没有遇到任何问题。
这是C#中的代码,希望对您有所帮助。请注意,代码是从Visual Basic 中的原始代码转换而来的,因此可能会出现一些转换错误。
//In Table Adapter
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
Common.DisposeTableAdapter(disposing, _adapter, _commandCollection);
}
public static class Common
{
/// <summary>
/// Disposes a TableAdapter generated by SQLite Designer
/// </summary>
/// <param name="disposing"></param>
/// <param name="adapter"></param>
/// <param name="commandCollection"></param>
/// <remarks>You must dispose all the command,
/// otherwise the file remains locked and cannot be accessed
/// (for example, for reading or deletion)</remarks>
public static void DisposeTableAdapter(
bool disposing,
System.Data.SQLite.SQLiteDataAdapter adapter,
IEnumerable<System.Data.SQLite.SQLiteCommand> commandCollection)
{
if (disposing) {
DisposeSQLiteTableAdapter(adapter);
foreach (object currentCommand_loopVariable in commandCollection)
{
currentCommand = currentCommand_loopVariable;
currentCommand.Dispose();
}
}
}
public static void DisposeSQLiteTableAdapter(
System.Data.SQLite.SQLiteDataAdapter adapter)
{
if (adapter != null) {
DisposeSQLiteTableAdapterCommands(adapter);
adapter.Dispose();
}
}
public static void DisposeSQLiteTableAdapterCommands(
System.Data.SQLite.SQLiteDataAdapter adapter)
{
foreach (object currentCommand_loopVariable in {
adapter.UpdateCommand,
adapter.InsertCommand,
adapter.DeleteCommand,
adapter.SelectCommand})
{
currentCommand = currentCommand_loopVariable;
if (currentCommand != null) {
currentCommand.Dispose();
}
}
}
}
更新 2013-07-05 17:36 UTC gorogm 的回答强调了两个重要的事情:
根据 System.Data.SQLite 官方网站上的更改日志,从 1.0.84.0 版本开始,应该不需要上面的代码,因为库会处理这个问题。我没有对此进行测试,但在最坏的情况下你只需要这个片段:
//In Table Adapter
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
this.Adapter.Dispose();
}
关于Dispose
调用的实现TableAdapter
:最好将其放在部分类中,以便数据集重新生成不会影响此代码(以及您可能需要添加的任何其他代码)。