我使用與System.Data.Sqlite.dll
版本1.0.82.0一起提供的設計器生成的數據集/表適配器有同樣的問題 - 關閉連接後,我們無法使用System.IO.FileStream
讀取數據庫文件。我正確處理連接和tableadapters,我沒有使用連接池。
根據我的第一次搜索(例如this和this thread),這似乎是圖書館本身存在的一個問題 - 無論是對象未正確釋放還是共用問題(我不使用)。
閱讀完您的問題後,我嘗試僅使用SQLiteCommand對象複製問題,並且發現問題出現在您不處理它們時。 更新2012-11-27 19:37 UTC:System.Data.SQLite的this ticket進一步證實了這一點,其中開發人員解釋說「全部與連接關聯的SQLiteCommand和SQLiteDataReader對象[應該]正確處置」。
然後我又回到生成的TableAdapters上,我看到沒有實現Dispose
方法 - 所以實際上創建的命令沒有被處置。我實現了它,負責處理所有的命令,而且我沒有問題。
以下是C#中的代碼,希望對您有所幫助。請注意,代碼是從original in 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年7月5日17:36 UTCgorogm's answer突出了兩個重要的事情:
根據changelog上System.Data.SQLite的官方網站,從版本開始1.0.84.0上面的代碼不應該被需要,因爲庫處理這個。我沒有測試過這一點,但在最壞的情況下,你只需要這個片段:
//In Table Adapter
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
this.Adapter.Dispose();
}
有關Dispose
呼叫TableAdapter
的執行:它是最好把這個分部類,所以數據集重新生成不會影響此代碼(以及您可能需要添加的任何其他代碼)。
你是否在使用語句中包裝命令和連接? – Arran
您的應用程序是否鎖定該鎖定,即鎖定退出時是否消失? –
@Arran我不打包使用連接。但即使使用沒有鎖定的版本(即使用命令而不是數據適配器),我也不打包它。 –