SQLite を使用したローカルへのデータの格納
リレーショナル データがある場合は、SQLite が便利です。 ソーシャル メディア アプリを構築しているとしましょう。 アプリのサブスクライバーに関する情報を格納する必要があります。 このデータには、各ユーザーの一意の ID とその名前が含まれています。 この種のリレーションシップは、SQLite データベースで簡単にモデル化することができます。
このユニットでは、SQLite-net を使って .NET MAUI アプリケーションで SQLite を使用する方法について学習します。
SQLite とは
SQLite は、モバイル アプリケーション用の業界標準である軽量のクロスプラットフォーム ローカル データベースです。 SQLite にはサーバーは必要ありません。 データベースは、デバイスのファイル システム上の 1 つのディスク ファイルに格納されます。 すべての読み取りと書き込み操作は、SQLite のディスク ファイルに対して直接実行されます。
SQLite のネイティブ ライブラリは、既定では Android および iOS に組み込まれます。ただし、エンジンでは C/C++ API のみがサポートされます。 このシナリオは、SQLite と .NET がやりとりする何らかの方法を必要とする、.NET 開発者には適していません。
SQLite-net とは
.NET 開発者が使用できる、ネイティブ SQLite エンジンの C# ラッパーがいくつかあります。 多くの .NET 開発者は、SQLite-net というよく使用される C# ラッパーを使用しています。
SQLite-net はオブジェクト リレーショナル マッパーです。 これを使用すると、プロジェクトで定義されているモデルをスキーマとして提供できるようになり、データベース スキーマを定義するプロセスを簡素化するのに役立ちます。
例として、User をモデル化する次のクラスについて考えてみましょう。
class User
{
public int Id { get; set; }
public string Username { get; set; }
...
}
オブジェクト リレーショナル マッパーを使用すると、この最初の User クラスを取得して、このクラスの User および Id フィールド用の列を含む Username という名前のデータベース テーブルを作成できます。
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# クラスを定義した後、CreateTable クラスの SQLiteConnection ジェネリック メソッドを呼び出して、データベースにテーブルを生成します。 型パラメーターとしてクラスを指定します。 次に例を示します。
SQLiteConnection conn = new SQLiteConnection(filename);
conn.CreateTable<User>();
データベースに既にテーブルが存在する場合は、CreateTable メソッドによって、スキーマに変更があるかどうかが確認されます。 ある場合、操作はデータベース スキーマの更新を試みます。
基本的な読み取りと書き込み操作を行う方法
テーブルを作成した後、その操作を開始できます。 行を追加するには、Insert インスタンスで SQLiteConnection メソッドを使用し、挿入するデータを保持する適切な型のオブジェクトを指定します。 次のコードでは、User テーブルに新しい行を追加する方法を示します。
public int AddNewUser(User user)
{
int result = conn.Insert(user);
return result;
}
Insert メソッドから int が返されます。これはテーブルに挿入された行の数を表します。 この場合、その数は 1 です。
テーブルから行を取得するには、Table メソッドを使用します。 次のメソッドでは、オブジェクトのコレクションが返されます (空の場合があります)。
public List<User> GetAllUsers()
{
List<User> users = conn.Table<User>().ToList();
return users;
}
Table メソッドが TableQuery\<T> オブジェクトを返します。
List を取得するには、前の例に示すように ToList メソッドを使用します。
LINQ を使用して SQLite クエリを実行する
Table メソッドでは、テーブルからすべての行が取得されます。 ほとんどの場合、指定した条件のセットに一致する行のサブセットのみが返されるようにする必要があります。 これらのタスクには、SQLite-net で LINQ を使います。
SQLite-net では、次のような多くの一般的な LINQ クエリがサポートされています。
WhereTakeSkipOrderByOrderByDescendingThenByElementAtFirstFirstOrDefaultThenByDescendingCount
これらのメソッドでは、拡張メソッド構文または 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 メソッドは、指定されたオブジェクトと同じ主キー値を持つ行を変更します。 返される値は、変更された行の数です。 この値が 0 の場合、主キーが一致する行が見つからず、何も更新されませんでした。 次のスニペットでは、このメソッドの動作を示します。
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;
}