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
クラスを取得して、このクラスの Id
および Username
フィールド用の列を含む User
という名前のデータベース テーブルを作成できます。
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
が返されます。これはテーブルに挿入された行の数を表します。 この場合、その数は 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 クエリがサポートされています。
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
メソッドは、指定されたオブジェクトと同じ主キー値を持つ行を変更します。 返される値は、変更された行の数です。 この値が 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;
}