我的代碼中有一個方法,它將sqlite3 db初始化到指定目錄,如以下代碼片段所示:
using System;
using System.IO;
using Microsoft.Data.Sqlite;
namespace test
{
public static class DatabaseUtils
{
public static void InitializeDatabase(string directoryPath)
{
if (!Directory.Exists(directoryPath))
{
throw new Exception();
}
string sqliteFile = Path.Combine(Path.GetFullPath(directoryPath), "test.sqlite3");
if (File.Exists(sqliteFile))
{
throw new Exception();
}
else
{
try
{
File.Create(sqliteFile).Dispose();
using (SqliteConnection connection = new SqliteConnection($"Data Source={sqliteFile};Mode=ReadWrite"))
{
connection.Open();
using (SqliteCommand command = new SqliteCommand())
{
command.Connection = connection;
command.CommandText = "DROP TABLE IF EXISTS MyTable; CREATE TABLE MyTable (Primary_Key INTEGER PRIMARY KEY, Text_Entry NVARCHAR(2048) NULL)";
command.ExecuteNonQuery();
}
connection.Close();
}
}
catch (Exception)
{
throw;
}
}
}
}
}
案例1:第一次呼叫這個方法時,一切正常。這意味著 => 資料庫檔案是使用代碼中指定的 table(MyTable) 創建的。
案例2:第二次呼叫此方法時,手動洗掉資料庫檔案后,創建資料庫檔案時沒有代碼中指定的表(MyTable),出現如下錯誤=> SQLite Error 8: 'attempt to write a只讀資料庫'
在我看來,好像在第一次運行后沒有正確處理與資料庫的連接,或者在第一次運行期間創建的資料庫以某種方式快取在記憶體中。
預期行為: 當滿足上述條件時,方法應在每次呼叫時創建具有指定表的 sqlite 資料庫檔案。
使用的包: “Microsoft.Data.Sqlite,版本 6.0.2”,“PowerShellStandard.Library,版本 5.1.0”
目標框架: .NET 6
值得一提的是: 當用 'Mode=ReadWriteCreate' ConnectionString 替換 'File.Create()' 方法時,手動洗掉后不會第二次創建檔案。僅在第一個方法運行期間。
編輯: 將 'Microsoft.Data.Sqlite' 替換為 'System.Data.SQLite.Core',現在該方法每次都按預期作業。
我想這要么是“Microsoft.Data.Sqlite”中的 BUG,要么我只是錯過了這兩個庫之間的重要區別。
很高興得到 MSFT 開發人員關于我做錯了什么的官方回答。
uj5u.com熱心網友回復:
打開和關閉連接 2 次可能會出現問題:您可以這樣嘗試嗎:
using (SQLiteConnection connection = new SQLiteConnection($"Data Source={SqliteFile};Mode=ReadWrite"))
{
using (SQLiteCommand command = new SQLiteCommand())
{
command.Connection = connection;
command.CommandText = "DROP TABLE IF EXISTS MyTable; CREATE TABLE MyTable (Primary_Key INTEGER PRIMARY KEY, Text_Entry NVARCHAR(2048) NULL)";
command.ExecuteNonQuery();
}
}
uj5u.com熱心網友回復:
啊,好吧,我錯過了一部分。對我來說,它總是這樣作業(簡而言之):
private SQLiteConnection OpenDataBase(string dataBasePath)
{
SQLiteConnection connection = new SQLiteConnection($@"Data Source = {dataBasePath}; Version = 3; New = True; Compress = True; ");
connection.Open();
return connection;
}
public void CreateTable(string dataBasePath)
{
using (SQLiteConnection? connection = OpenDataBase(dataBasePath))
{
string create = "DROP TABLE IF EXISTS MyTable; CREATE TABLE MyTable (Primary_Key INTEGER PRIMARY KEY, Text_Entry NVARCHAR(2048) NULL)"; ;
using (SQLiteCommand command = new SQLiteCommand(create, connection))
{
command.ExecuteNonQuery();
}
}
}
uj5u.com熱心網友回復:
在 github 中深入挖掘之后,我找到了原始問題的實際答案。有一個稱為“連接池”的功能,它導致了我在問題中描述的這種“意外行為”。
要禁用此功能,請將“Pooling=False”添加到 ConnectionString,或在您希望處理連接的位置呼叫“SqliteConnection.ClearAllPools()”(使用陳述句是不夠的)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/430518.html
下一篇:選擇查詢一對多關系表?
