.NET MAUI 本機資料庫
SQLite 資料庫引擎可讓 .NET 多平臺應用程式 UI (.NET MAUI) 應用程式在共用程式碼中載入和儲存資料物件。 您可以遵循下列步驟,將 SQLite.NET 整合到 .NET MAUI 應用程式中,以在本機資料庫中儲存和擷取資訊:
本文使用 sqlite-net-pcl NuGet 套件,為數據表提供 SQLite 資料庫存取權來儲存 todo 專案。 替代方法是使用 Microsoft.Data.Sqlite NuGet 套件,這是 SQLite 的輕量 型 ADO.NET 提供者。 Microsoft.Data.Sqlite 會針對連線、命令和數據讀取器等功能實作常見的 ADO.NET 抽象概念。
安裝 SQLite NuGet 套件
使用 NuGet 套件管理員來搜尋 sqlite-net-pcl 套件,並將最新版本新增至 .NET MAUI 應用程式專案。
有許多名稱類似的 NuGet 套件。 正確的套件有下列屬性:
- 識別碼: sqlite-net-pcl
- 作者: SQLite-net
- 擁有者:praeclarum
- NuGet 連結:sqlite-net-pcl
儘管套件名稱,但在 .NET MAUI 專案中使用 sqlite-net-pcl NuGet 套件。
重要
SQLite.NET 是 praeclarum/sqlite-net 存放庫所支援的第三方連結庫。
安裝SQLitePCLRaw.bundle_green
除了 sqlite-net-pcl 之外,您 暫時 還需要在每個平臺上安裝公開 SQLite 的基礎相依性:
- 標識碼: SQLitePCLRaw.bundle_green
- Version:>= 2.1.0
- 作者: Eric Sink
- 擁有者: Eric Sink
- NuGet 連結:SQLitePCLRaw.bundle_green
設定應用程式常數
設定數據,例如資料庫檔名和路徑,可以儲存為應用程式中的常數。 範例專案包含提供 一般組態數據的Constants.cs 檔案:
public static class Constants
{
public const string DatabaseFilename = "TodoSQLite.db3";
public const SQLite.SQLiteOpenFlags Flags =
// open the database in read/write mode
SQLite.SQLiteOpenFlags.ReadWrite |
// create the database if it doesn't exist
SQLite.SQLiteOpenFlags.Create |
// enable multi-threaded database access
SQLite.SQLiteOpenFlags.SharedCache;
public static string DatabasePath =>
Path.Combine(FileSystem.AppDataDirectory, DatabaseFilename);
}
在此範例中,常數檔案會指定用來初始化資料庫連接的預設 SQLiteOpenFlag
列舉值。 列舉 SQLiteOpenFlag
支援下列值:
Create
:如果連接不存在,聯機會自動建立資料庫檔案。FullMutex
:連線是以串行化線程模式開啟。NoMutex
:連線是以多線程模式開啟。PrivateCache
:即使連線已啟用,連線也不會參與共用快取。ReadWrite
:連接可以讀取和寫入數據。SharedCache
:如果已啟用共用快取,連線將會參與共用快取。ProtectionComplete
:在鎖定裝置時,檔案會加密且無法存取。ProtectionCompleteUnlessOpen
:檔案會在開啟之前加密,但即使使用者鎖定裝置,仍可存取該檔案。ProtectionCompleteUntilFirstUserAuthentication
:檔案會在用戶開機並解除鎖定裝置之前加密。ProtectionNone
:資料庫檔案未加密。
您可能需要根據資料庫的使用方式來指定不同的旗標。 如需 的詳細資訊 SQLiteOpenFlags
,請參閱 在 sqlite.org 上開啟新的資料庫連接 。
建立數據庫存取類別
資料庫包裝函式類別會從應用程式的其餘部分擷取數據存取層。 這個類別會集中查詢邏輯,並簡化資料庫初始化的管理,讓您在應用程式成長時更輕鬆地重構或擴充數據作業。 範例應用程式會為此目的定義類別 TodoItemDatabase
。
延遲初始化
使用 TodoItemDatabase
異步延遲初始化來延遲資料庫初始化,直到資料庫第一次存取為止,方法是使用類別中每個方法所呼叫的簡單 Init
方法:
public class TodoItemDatabase
{
SQLiteAsyncConnection Database;
public TodoItemDatabase()
{
}
async Task Init()
{
if (Database is not null)
return;
Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
var result = await Database.CreateTableAsync<TodoItem>();
}
...
}
數據操作方法
類別 TodoItemDatabase
包含四種數據操作類型的方法:建立、讀取、編輯和刪除。 SQLite.NET 連結庫提供簡單的物件關係型對應 (ORM),可讓您儲存和擷取物件,而不需要撰寫 SQL 語句。
下列範例顯示範例應用程式中的數據操作方法:
public class TodoItemDatabase
{
...
public async Task<List<TodoItem>> GetItemsAsync()
{
await Init();
return await Database.Table<TodoItem>().ToListAsync();
}
public async Task<List<TodoItem>> GetItemsNotDoneAsync()
{
await Init();
return await Database.Table<TodoItem>().Where(t => t.Done).ToListAsync();
// SQL queries are also possible
//return await Database.QueryAsync<TodoItem>("SELECT * FROM [TodoItem] WHERE [Done] = 0");
}
public async Task<TodoItem> GetItemAsync(int id)
{
await Init();
return await Database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();
}
public async Task<int> SaveItemAsync(TodoItem item)
{
await Init();
if (item.ID != 0)
return await Database.UpdateAsync(item);
else
return await Database.InsertAsync(item);
}
public async Task<int> DeleteItemAsync(TodoItem item)
{
await Init();
return await Database.DeleteAsync(item);
}
}
存取資料
如果您使用相依性插入,則可以 TodoItemDatabase
將 類別註冊為單一類別,以在整個應用程式中使用。 例如,您可以使用 和 AddTransient
方法,在 MauiProgram.csAddSingleton
中,將頁面和數據庫存取類別註冊為物件上的IServiceCollection服務:
builder.Services.AddSingleton<TodoListPage>();
builder.Services.AddTransient<TodoItemPage>();
builder.Services.AddSingleton<TodoItemDatabase>();
然後,這些服務可以自動插入類別建構函式,並加以存取:
TodoItemDatabase database;
public TodoItemPage(TodoItemDatabase todoItemDatabase)
{
InitializeComponent();
database = todoItemDatabase;
}
async void OnSaveClicked(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(Item.Name))
{
await DisplayAlert("Name Required", "Please enter a name for the todo item.", "OK");
return;
}
await database.SaveItemAsync(Item);
await Shell.Current.GoToAsync("..");
}
或者,也可以建立數據庫存取類別的新實例:
TodoItemDatabase database;
public TodoItemPage()
{
InitializeComponent();
database = new TodoItemDatabase();
}
如需 .NET MAUI 應用程式中相依性插入的詳細資訊,請參閱 相依性插入。
進階設定
SQLite 提供強固的 API,其功能比本文和範例應用程式所涵蓋的功能還多。 下列各節涵蓋對於延展性而言很重要的功能。
如需詳細資訊,請參閱 sqlite.org 的 SQLite 檔 。
預寫記錄
根據預設,SQLite 會使用傳統的回復日誌。 未變更的資料庫內容複本會寫入個別的回復檔案,然後變更會直接寫入資料庫檔案。 刪除回復日誌時,就會發生 COMMIT。
預先寫入記錄 (WAL) 會先將變更寫入個別的 WAL 檔案。 在 WAL 模式中,COMMIT 是附加至 WAL 檔案的特殊記錄,可讓單一 WAL 檔案中發生多個交易。 WAL 檔案會在稱為 檢查點的特殊作業中,合併回資料庫檔案。
WAL 對於本機資料庫來說可能更快,因為讀取器和寫入器不會彼此封鎖,因此允許讀取和寫入作業同時運作。 不過,WAL 模式不允許變更 頁面大小、將其他檔案關聯新增至資料庫,以及新增額外的 檢查點 作業。
若要在 SQLite.NET 中啟用 WAL,請在 實體上SQLiteAsyncConnection
呼叫 EnableWriteAheadLoggingAsync
方法:
await Database.EnableWriteAheadLoggingAsync();
如需詳細資訊,請參閱 SQLite 預先寫入記錄 sqlite.org。
複製資料庫
在某些情況下,可能需要複製 SQLite 資料庫:
- 資料庫隨附於您的應用程式,但必須複製或移至行動裝置上的可寫入記憶體。
- 您必須建立資料庫的備份或複本。
- 您需要版本、移動或重新命名資料庫檔案。
一般而言,移動、重新命名或複製資料庫檔案的程式與任何其他檔類型的程式相同,但有一些其他考慮:
- 嘗試移動資料庫檔案之前,應該先關閉所有資料庫連接。
- 如果您使用 Write-Ahead 記錄,SQLite 會建立共用記憶體存取 (.shm) 檔案和 [寫入預先記錄] (.wal) 檔案。 請確定您也對這些檔案套用任何變更。