SQLite數(shù)據(jù)操作流程
- 打開(kāi)數(shù)據(jù)庫(kù)連接
- 針對(duì)要操作的數(shù)據(jù)庫(kù)闹究,建立一個(gè)
SQLiteConnection
實(shí)例connection
囚玫。然后調(diào)用connection.Open()
- 這個(gè)連接實(shí)例在生存期內(nèi)都是與數(shù)據(jù)庫(kù)文件綁定的霜医,也就是這個(gè)連接實(shí)例存在期間,你是不能對(duì)數(shù)據(jù)庫(kù)文件做刪除等操作的。
- 針對(duì)要操作的數(shù)據(jù)庫(kù)闹究,建立一個(gè)
- 創(chuàng)建事務(wù)
- 執(zhí)行操作,這里的
操作
對(duì)應(yīng)的是SQLite中的Command
朗若。它是對(duì)SQL語(yǔ)句的封裝。根據(jù)操作的不同昌罩,一般我們主要使用兩種執(zhí)行方式。- 需要返回?cái)?shù)據(jù)灾馒。比如查茎用。可以通過(guò)
command.ExecuteReader()
返回的SQLiteDataReader
對(duì)數(shù)據(jù)進(jìn)行讀取工作睬罗。 - 不需要返回?cái)?shù)據(jù)轨功。比如增刪改∪荽铮可以通過(guò)
command.ExecuteNonQuery()
古涧,該函數(shù)返回?cái)?shù)據(jù)庫(kù)中受影響的列數(shù)。
- 需要返回?cái)?shù)據(jù)灾馒。比如查茎用。可以通過(guò)
- 提交事務(wù)花盐,至此操作完成羡滑。
- 關(guān)閉數(shù)據(jù)庫(kù)連接,調(diào)用
connection.Close()
算芯∑饣瑁可選。- 如數(shù)據(jù)庫(kù)操作很少熙揍,建議使用之后及時(shí)關(guān)閉职祷。
- 如果會(huì)頻繁使用,建議保留連接届囚,避免每次需要都創(chuàng)建有梆。
詳細(xì)步驟
在項(xiàng)目中引入SQLite
右鍵項(xiàng)目選擇 管理NuGet包:
管理Nuget包
接下來(lái)安裝SQLite.Core
安裝SQLite.Core
代碼實(shí)例
- 創(chuàng)建數(shù)據(jù)庫(kù)連接,我傾向于使用一個(gè)全局靜態(tài)變量來(lái)一直保存數(shù)據(jù)庫(kù)連接意系。
// 數(shù)據(jù)庫(kù)文件夾 static string DbPath = Path.Combine(YatesHelper.GetAppDefaultPath(), "Database"); //與指定的數(shù)據(jù)庫(kù)(實(shí)際上就是一個(gè)文件)建立連接 private static SQLiteConnection CreateDatabaseConnection(string dbName = null) { if (!string.IsNullOrEmpty(DbPath) && !Directory.Exists(DbPath)) Directory.CreateDirectory(DbPath); dbName = dbName == null ? "database.db" : dbName; var dbFilePath = Path.Combine(DbPath, dbName); return new SQLiteConnection("DataSource = " + dbFilePath); } // 使用全局靜態(tài)變量保存連接 private static SQLiteConnection connection = CreateDatabaseConnection();
- 打開(kāi)數(shù)據(jù)庫(kù)連接
// 判斷連接是否處于打開(kāi)狀態(tài) private static void Open(SQLiteConnection connection) { if (connection.State != System.Data.ConnectionState.Open) { connection.Open(); } }
- 使用事務(wù)泥耀,使用using語(yǔ)句會(huì)使代碼比較清晰。
using (var tr = connection.BeginTransaction())
- 執(zhí)行非查詢SQL語(yǔ)句代碼昔字,適用于建表爆袍、增刪改等首繁。
public static void ExecuteNonQuery(string sql) { // 確保連接打開(kāi) Open(connection); using (var tr = connection.BeginTransaction()) { using (var command = connection.CreateCommand()) { command.CommandText = sql; command.ExecuteNonQuery(); } tr.Commit(); } }
- 執(zhí)行查詢語(yǔ)句,因?yàn)椴樵兩婕暗骄唧w的數(shù)據(jù)陨囊,這里只詳細(xì)解釋方法含義弦疮。
public static void ExecuteQuery(string sql) { // 確保連接打開(kāi) Open(connection); using (var tr = connection.BeginTransaction()) { using (var command = connection.CreateCommand()) { command.CommandText = sql; // 執(zhí)行查詢會(huì)返回一個(gè)SQLiteDataReader對(duì)象 var reader = command.ExecuteReader(); //reader.Read()方法會(huì)從讀出一行匹配的數(shù)據(jù)到reader中。注意:是一行數(shù)據(jù)蜘醋。 while (reader.Read()) { // 有一系列的Get方法胁塞,方法的參數(shù)是列數(shù)。意思是獲取第n列的數(shù)據(jù)压语,轉(zhuǎn)成Type返回啸罢。 // 比如這里的語(yǔ)句,意思就是:獲取第0列的數(shù)據(jù)胎食,轉(zhuǎn)成int值返回扰才。 var time = reader.GetInt64(0); } } tr.Commit(); } }
- 如何刪除數(shù)據(jù)庫(kù)?
// 因?yàn)镾QLite是文件型數(shù)據(jù)庫(kù)厕怜,可以直接刪除文件衩匣。但只要數(shù)據(jù)庫(kù)連接沒(méi)有被回收,就無(wú)法刪除文件粥航。 public static void DeleteDatabase(string dbName) { var path = Path.Combine(DbPath, dbName); connection.Close(); // 置空琅捏,手動(dòng)GC,并等待GC完成后執(zhí)行文件刪除递雀。 connection = null; GC.Collect(); GC.WaitForPendingFinalizers(); File.Delete(path); }
問(wèn)題
遇到的問(wèn)題柄延,主要是打包安裝后會(huì)出現(xiàn)。問(wèn)題的原因其實(shí)是一致的缀程。如果你捕獲了全局異常搜吧,就能從異常信息中得到錯(cuò)誤原因。
SQLite.Interop.dll
的問(wèn)題
System.BadImageFormatException: 試圖加載格式不正確的程序杠输。
System.DllNotFoundException: 無(wú)法加載 DLL“SQLite.Interop.dll”: 找不到指定的模塊赎败。
這個(gè)是因?yàn)閺腘uGet獲得的包內(nèi)是沒(méi)有SQLite.Interop.dll
的,但是在Debug的時(shí)候蠢甲,它會(huì)自動(dòng)生成對(duì)應(yīng)平臺(tái)的dll僵刮。可以看一下項(xiàng)目目錄下(../packages/System.Data.SQLite/build
)
build文件夾
里面有各個(gè).NET
版本的對(duì)應(yīng)平臺(tái)的SQLite.Interop.dll
鹦牛。打包的時(shí)候搞糕,將對(duì)應(yīng)的文件一起打包即可。如果要兼顧x86
和x64
曼追,也可以在打包時(shí)指定在應(yīng)用文件夾窍仰,創(chuàng)建x86
和x64
目錄,并將對(duì)應(yīng)的SQLite.Interop.dll
放進(jìn)去礼殊。這也是最保險(xiǎn)的方法驹吮。
分平臺(tái)打包
應(yīng)用沒(méi)有應(yīng)用文件夾的訪問(wèn)權(quán)限
以管理員權(quán)限運(yùn)行即可针史。