使用 SQLite 在本機儲存資料

已完成

當您有關聯式資料時,SQLite 將有其效用。 假設您要建置社交媒體應用程式。 您需要將訂閱者的相關資訊儲存至應用程式。 這項資料包括每個使用者的唯一識別碼及其名稱。 您可以在 SQLite 資料庫中輕鬆地建立這種關聯性的模型。

在此單元中,您會了解如何利用 SQLite-net 在 .NET MAUI 應用程式中使用 SQLite。

什麼是 SQLite?

SQLite 是輕量型的跨平台本機資料庫,它是行動應用程式的產業標準。 SQLite 不需要伺服器。 資料庫會儲存在裝置檔案系統的單一磁碟檔案中。 所有讀取和寫入作業會直接在 SQLite 磁碟檔案執行。

根據預設,SQLite 原生程式庫內建於 Android 和 iOS;不過,引擎僅支援 C/C++ API。 這對於 .NET 開發人員來說不是最理想的狀況,他們需要某種方式讓 .NET 與 SQLite 互動。

什麼是 SQLite-net?

原生 SQLite 引擎有幾個 C# 包裝函式可讓 .NET 開發人員使用。 許多 .NET 開發人員均使用名為 SQLite-net 的熱門 C# 包裝函式。

SQLite-net 是物件關聯式對應程式。 它透過讓您使用在專案中定義的模型作為結構描述,從而簡化定義資料庫結構的程序。

顯示 SQLite-net 如何提供 .NET 包裝函式和 SQLite C/C++ 引擎的圖表。

例如,請考慮建立 User 模型的下列類別:

class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    ...
}

藉由使用物件關聯式對應工具,您可以採用這個初始 User 類別,並建立名為 User 的資料庫資料表,其具有此類別中 IdUsername 欄位的資料行。

SQLite-net 隨附為 NuGet 套件。 您必須將 sqlite-net-pcl 套件新增至應用程式,才能加以使用。

如何連線至 SQLite 資料庫

您可以透過 SQLiteConnection 物件建立從應用程式到 SQLite 資料庫的連線。 這個類別,以及 SQLite 提供的其他類型和方法定義在 SQLite 命名空間中。 在具現化此物件時,必須傳入資料庫檔案的檔案名稱。 然後建構函式會開啟檔案 (如果存在) 或建立該檔案 (如果不存在)。

下列程式碼顯示一個範例:

using SQLite;
...
string filename = ...
SQLiteConnection conn = new SQLiteConnection(filename);

請記住,filename 應指向應用程式沙箱中的位置。

如何建立資料表

您應該記得,SQLite-net 是物件關聯式對應程式,這表示您可以從 C# 類別建置您的資料庫結構描述。 SQLite-net 可從一般 C# 類別建置資料庫資料表,但您可以在類別中新增許多屬性以提供更多中繼資料。 此中繼資料可協助 SQLite 強制執行唯一性等功能,以及將條件約束套用至您的資料。

可用的屬性包括:

  • Table:指定資料表的名稱 (如果您想要類別名稱以外的名稱)。
  • PrimaryKey:指定資料行是主索引鍵。
  • AutoIncrement:指定資料行應於插入新資料列時自動增加值。
  • Column:指定資料行的名稱 (如果您想要屬性名稱以外的名稱)。
  • MaxLength:指定資料行中的最大可用字元數。
  • Unique:指定資料行中之值必須是其他所有資料列中的唯一。

下列程式碼顯示套用這些屬性的 User 類別的更新版本:

[Table("user")]
public class User
{
    // PrimaryKey is typically numeric 
    [PrimaryKey, AutoIncrement, Column("_id")]
    public int Id { get; set; }

    [MaxLength(250), Unique]
    public string Username { get; set; }
    ...
}

定義 C# 類別之後,請呼叫 SQLiteConnection 類別上的 CreateTable 泛型方法,以在資料庫中產生資料表。 將類別指定為類型參數。 以下是範例:

SQLiteConnection conn = new SQLiteConnection(filename);
conn.CreateTable<User>();

如果資料表已存在於資料庫中,CreateTable 方法會檢查結構描述,以查看是否有任何變更。 如果有的話,作業會嘗試更新資料庫結構描述。

如何執行基本的讀取和寫入作業

建立資料表之後,您可以開始與其互動。 若要新增資料列,請在 SQLiteConnection 執行個體上使用 Insert 方法,並提供保留要插入之資料的適當型別物件。 下列程式碼顯示如何將新的資料列新增至 User 資料表:

public int AddNewUser(User user)
{
    int result = conn.Insert(user);
    return result;
}

Insert 方法會傳回 int,這表示已插入至資料表的資料列數目。 在此案例中只有一個。

若要從資料表擷取資料列,請使用 Table 方法。 這個方法會傳回物件集合 (可能是空的):

public List<User> GetAllUsers()
{
    List<User> users = conn.Table<User>().ToList();
    return users;
}

Table 方法會傳回 TableQuery\<T> 物件。 若要取得 List,請使用 ToList 方法,如上述範例所示。

使用 LINQ 執行 SQLite 查詢

Table 方法會從資料表中擷取所有資料列。 在多數情況下,您只需要傳回與一組指定準則相符的資料列子集。 若要執行這些工作,請搭配使用 LINQ 與 SQLite-net。

SQLite-net 支援許多常見的 LINQ 查詢,包括:

  • Where
  • Take
  • Skip
  • OrderBy
  • OrderByDescending
  • ThenBy
  • ElementAt
  • First
  • FirstOrDefault
  • ThenByDescending
  • Count

藉由這些方法,您可以使用擴充方法語法或 LINQ C# 語法。 例如,以下是程式碼片段,可讓您擷取指定使用者的詳細資料:

public User GetByUsername(string username)
{
    var user = from u in conn.Table<User>()
               where u.Username == username
               select u;
    return user.FirstOrDefault();
}

更新及刪除資料列

您可以使用 SQLiteConnection 物件的 Update 方法更新資料列。 您可以提供一個物件,用以定義要以新值更新的資料列。 Update 方法會修改與所提供物件具有相同主索引鍵值的資料列。 傳回的值是從變更的資料列數目。 如果此值為零,則找不到具有相符主索引鍵的資料列,且不會更新任何資料列。 下一個程式碼片段顯示此方法的運作情形:

public int UpdateUser(User user)
{
    int result = 0;
    result = conn.Update(user);
    return result;
}

使用 SQLiteConnection 物件的 Delete 方法,從資料表中移除資料列。 此方法最簡單的形式,是採用要刪除之項目的主索引鍵做為參數,如下列範例所示。 這個 Delete 方法的形式是泛型的,而且需要型別參數。 傳回的值是從資料表中移除的資料列數目:

public int DeleteUser(int userID)
{
    int result = 0;
    result = conn.Delete<User>(userID);
    return result;
}