演習: SQLite を使用してデータをローカルに格納する

完了

この演習では、SQLite を使用して、アプリケーションと共にローカルに情報を格納します。 サンプル シナリオで、あなたは応答性を向上させるためにソーシャル メディア アプリのデータをキャッシュすることにしました。 この演習では、ユーザーに関する情報を格納するために、ローカルの SQLite データベースを作成して使用します。 物理データベース ファイルをローカル ストレージに保存します。

このモジュールでは、.NET 9.0 SDK を使います。 適切なコマンド ターミナルで次のコマンドを実行して、.NET 9.0 がインストールされていることを確認します。

dotnet --list-sdks

次の例のような出力が表示されます。

8.0.100 [C:\Program Files\dotnet\sdk]
9.0.100 [C:\Program Files\dotnet\sdk]

9 で始まるバージョンが一覧に表示されていることを確実にします。 何も表示されない場合、またはコマンドが見つからない場合は、最新の .NET 9.0 SDK をインストールしてください。

スターター ソリューションを開く

  1. exercise repo をクローンまたはダウンロードします。

    Note

    ビルドによって生成されたファイルが最大パス長を超えないようにするため、演習コンテンツを C:\dev などの短いフォルダー パスに複製するのが最善です。

  2. Visual Studio を使用して People.sln ソリューションを開きます。これは mslearn-dotnetmaui-store-local-data>People、または Visual Studio Code のスターター フォルダーで見つかります。

    Note

    まだアプリケーションを実行しないでください。コードは不完全であり、この演習の後半で不足している要素を追加するまで例外がスローされます。

SQLite エンティティを定義する

  1. [Models] フォルダー内の Person.cs ファイルを開きます。

  2. Person クラスに Id という名前の int プロパティを追加します。

  3. Name という名前の string プロパティを追加します。 クラスは次のようになります。

    namespace People.Models;
    
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
  4. Person.cs ファイルを保存します。

SQLite ライブラリを追加する

  1. Visual Studio のソリューション エクスプローラーから People プロジェクト ノードを右クリックします。

  2. 表示されたコンテキスト メニューで、[NuGet パッケージの管理] を選択します。

  3. sqlite-net-pcl を検索して選択した後、[インストール] を選択します。

    sqlite-net-pcl ライブラリが選択されている NuGet パッケージ マネージャーを示すスクリーンショット。

Visual Studio Code を使用している場合は、以下のコマンドでターミナルとこれらのパッケージを開きます。

dotnet add package sqlite-net-pcl

SQLite 属性を追加する

  1. Person.cs ファイル内で、Person クラスのファイルに SQLite 名前空間の using ディレクティブを追加します。 このディレクティブによって、SQLite の属性を使用できるようになります。

    using SQLite;
    
    namespace People.Models;
    
    public class Person
    {
        ...
    }
    
  2. Person クラスに [Table] 属性のアノテーションを付け、テーブル名を people と指定します。

  3. 主キーとして Id プロパティを指定します。 これに [PrimaryKey] および [AutoIncrement] 属性のアノテーションを付けます。

  4. Name プロパティにアノテーションを追加します。 MaxLength を 250 と指定します。 列の各値が Unique になるように指定します。

    完成したクラスは次のようになります。

    using SQLite;
    
    namespace People.Models;
    
    [Table("people")]
    public class Person
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
    
        [MaxLength(250), Unique]
        public string Name { get; set; }
    }
    
  5. Person.cs ファイルを保存します。

データベースに接続する

  1. PersonRepository.cs ファイルを開きます。

  2. PersonRepository クラスを調べます。 このクラスには、データベースにアクセスするための機能を追加する TODO マーカーを含む不完全なスケルトン コードが含まれています。

  3. PersonRepository.cs クラスのファイルに SQLite および People.Models 名前空間の using ディレクティブを追加します。

  4. conn という名前のプライベート SQLiteConnection フィールドを、クラスの Init 関数の上に追加します。

  5. Init 関数で、connnull と等しくないかを確認します。 その場合は、すぐに戻ります。

    if (conn != null)
        return;
    

    これにより、SQLite データベースの初期化コードは 1 回しか実行されなくなります。

  6. conn フィールドを初期化し、_dbPath 変数を使用してデータベースに接続します。

  7. conn.CreateTable メソッドを使用して、Person データを格納するテーブルを作成します。 完成した Init 関数は次のようになります。

    using SQLite;
    using People.Models;
    ...
    
    private SQLiteConnection conn;
    ...
    private void Init()
    {
       if (conn != null)
          return;
    
       conn = new SQLiteConnection(_dbPath);
       conn.CreateTable<Person>();
    }
    

データベースに行を挿入する

  1. PersonRepository クラスで、AddNewPerson メソッドを見つけます。

  2. 新しい Person オブジェクトを挿入するには、このメソッドの TODO コメントをコードに置き換えます。 このコードは、最初に Init を呼び出してデータベースが初期化されていることを確認した後、SQLiteConnection オブジェクトの Insert メソッドを使用します。 次のコードで示すように、result 変数を Insert メソッドが返す値に設定します。

    public void AddNewPerson(string name)
    {
        int result = 0;
        try
        {
            // enter this line
            Init();
    
            // basic validation to ensure a name was entered
            if (string.IsNullOrEmpty(name))
                throw new Exception("Valid name required");
    
            // enter this line
            result = conn.Insert(new Person { Name = name });
            ...
        }
        ...
    }
    

データベースから行を取得する

  1. PersonRepository クラスで、GetAllPeople メソッドを見つけます。

  2. Init を呼び出して、データベースが初期化されていることを確認します。

  3. ジェネリック Table\<T> メソッドを使用して、テーブル内のすべての行を取得します。 型パラメーターとして Person を指定します。

  4. ToList() 拡張メソッドを使用して結果を List\<Person> コレクションに変換し、このコレクションを返します。

  5. try-catch ブロックにコードをラップして、エラー処理を追加します。 エラーがある場合は、StatusMessage プロパティを例外の Message プロパティに設定して、空のコレクションを返します。 完成したメソッドは次のようになります。

    public List<Person> GetAllPeople()
    {
       try
       {
          Init();
          return conn.Table<Person>().ToList();
       }
       catch (Exception ex)
       {
          StatusMessage = string.Format("Failed to retrieve data. {0}", ex.Message);
       }
    
       return new List<Person>();
    }
    
  6. PersonRepository.cs ファイルを保存します。

リポジトリを UI に統合する

  1. MauiProgram.cs ファイルを開きます。

  2. CreateMauiApp 関数で、MainPage ページをシングルトン サービスとしてアプリに追加するステートメントの後に、以下のタスクを実行するコードを追加します。

    • dbPath という名前の文字列変数を作成します。 式 FileAccessHelper.GetLocalFilePath("people.db3") を使用してこの文字列を初期化します。 アプリで使用されるデータベース ファイルは people.db3 になり、このファイルはアプリによってデバイスのローカル ストレージに保存されます。

    • 依存関係の挿入を使用して、PersonRepository クラスをシングルトン サービスとしてアプリに追加します。 PersonRepository クラスは、データベース ファイルへのパスを文字列パラメーターとして受け取るコンストラクターを公開します。

    CreateMauiApp 関数の完成したコードは、次のようになります。

    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });
    
        // Add this code
        string dbPath = FileAccessHelper.GetLocalFilePath("people.db3");
        builder.Services.AddSingleton<PersonRepository>(s => ActivatorUtilities.CreateInstance<PersonRepository>(s, dbPath));
    
        return builder.Build();
    }
    
  3. MauiProgram.cs ファイルを保存します。

  4. ソリューション エクスプローラーで App.xaml を展開してから、App.xaml.cs ファイルを開きます。

  5. PersonRepo という名前の publicstatic プロパティを追加します。 このプロパティは、App クラスに PersonRepository オブジェクトを保持します。

  6. PersonRepository パラメーターをコンストラクターに追加し、'PersonRepo' プロパティをこのパラメーター内の値に設定することで、コンストラクター内で PersonRepo プロパティを初期化します。 完成した App クラスは次のようになります。

    public partial class App : Application
    {
        public static PersonRepository PersonRepo { get; private set; }
    
        public App(PersonRepository repo)
        {
            InitializeComponent();
            PersonRepo = repo;
        }
    }
    

Note

コンストラクターへの repo パラメーターは、依存関係注入プロセスによって自動的に設定されます。

アプリケーションをテストする

  1. Ctrl + Shift + B. キーを押して、ソリューションをビルドします。

  2. ビルドが完了したら、F5 キーを押してデバッグを始めます。 UI が表示されたら、自分の名前を入力して [人物の追加] を選択します。

    レコードの追加が正常に行われたことを示すメッセージが表示されたアプリのスクリーンショット。

  3. [すべての人物を取得] を選択して、自分の名前が表示されることを確認します。

    データベース内のすべてのレコードの一覧を含むアプリのスクリーンショット。

  4. さらに名前を追加し、保存されたユーザーのリストを取得してみます。

  5. Visual Studio または Visual Studio Code に戻り、Shift+F5 キーを使用してデバッグを停止します。

  6. アプリを再起動し、[すべての人物を取得] を選択します。 以前に保存した名前がまだデータベースに保存されていることを確認します。 完了したら、アプリを閉じます。