次の方法で共有


Windows アプリで SQLite データベースを使用する

SQLite は、Windows アプリにデータをローカルに格納するための信頼性の高い軽量データベース ソリューションを提供します。 個別のサーバー インストールと複雑な構成を必要とする従来のデータベース システムとは異なり、SQLite はアプリケーション プロセス内で完全に実行され、ユーザーのデバイス上の 1 つのファイルにデータを格納します。

このチュートリアルでは、Microsoft の推奨されるデータ アクセス ライブラリを使用して、SQLite を WinUI アプリケーションに統合する方法について説明します。 一般的な脆弱性から保護するためのセキュリティのベスト プラクティスに従いながら、データベースの設定、テーブルの作成、基本的なデータ操作の実装について学習します。

作業内容

このチュートリアルでは、次の方法について説明します。

  • Microsoft.Data.SQLite ライブラリで SQLite を使用するように Windows アプリを構成する
  • ローカル データベースを作成して初期化する
  • セキュリティで保護されたデータの挿入と取得の方法を実装する
  • データを操作するためのシンプルなユーザー インターフェイスを構築する

[前提条件]

このチュートリアルを完了するには、次のものが必要です。

  • Visual Studio 2022 以降と WinUI アプリケーション開発 ワークロード
  • C# と XAML に関する基本的な知識
  • データベースの基本的な概念の理解

このアプローチで提供される主な改善点

Windows アプリでローカル データ ストレージに SQLite を使用すると、次のような利点があります。

  • デプロイの簡略化: 個別のデータベース サーバーのインストールは必要ありません
  • セキュリティ強化: データはユーザーのデバイス上でローカルのまま
  • パフォーマンスの向上: 直接ファイル アクセスにより、ネットワーク待ち時間を排除
  • 複雑さの軽減: 単一ファイル データベースを使用すると、バックアップと移行が簡略化されます

学習する手法は、単純な設定ストレージから複雑なデータ管理シナリオまで、構造化データをローカルに格納する必要がある Windows アプリに適用されます。

ヒント

AI アシスタンスを使用して 、SQLite での SQL インジェクション攻撃を回避できます。

ローカル ストレージ用の SQLite の利点

✔️ SQLite は軽量で自己完結型です。 その他の依存関係がないコード ライブラリです。 構成する必要がありません。

✔️ データベース サーバーはありません。 クライアントとサーバーは、同じプロセスで実行されます。

✔️ SQLite はパブリック ドメインにあるため、アプリで自由に使用して配布できます。

✔️ SQLite はプラットフォームやアーキテクチャにかかわらず動作します。

SQLite について詳しくは、こちらをご覧ください。

アブストラクション レイヤーを選択する

Entity Framework Core、または Microsoft が構築したオープン ソースの SQLite ライブラリを使用することをお勧めします。

Entity Framework Core

Entity Framework (EF) は、ドメイン固有のオブジェクトを使ってリレーショナル データを操作できる、オブジェクト リレーショナル マッパーです。 既にこのフレームワークを使用して他の .NET アプリのデータを操作している場合は、WinUI アプリで同じコードを使用でき、接続文字列に対する適切な変更が処理されます。

試してみるには、「EF Core の概要」を参照してください。

SQLite ライブラリ

Microsoft.Data.Sqlite ライブラリでは、System.Data.Common 名前空間内にインターフェイスを実装しています。 Microsoft では、これらの実装をアクティブに保守しています。これらの実装によって、低レベルのネイティブ SQLite API に関する直感的なラッパーを提供します。

このガイドの残りの部分では、このライブラリの使用について説明します。

Microsoft.Data.SQLite ライブラリを使用するようにソリューションを設定する

基本的な WinUI プロジェクトから始めて、SQLite NuGet パッケージをインストールします。 最初 の WinUI プロジェクトを作成 する方法については、「WinUI アプリの作成」を参照してください。

サポートされているすべてのバージョンの Windows では SQLite がサポートされているため、アプリで SQLite ライブラリをパッケージ化する必要はありません。 代わりに、アプリでは Windows と共にインストールされるバージョンの SQLite を使用することができます。 これにより、次のような利点が得られます。

✔️ SQLite バイナリをダウンロードして、アプリケーションの一部としてパッケージ化する必要がないため、アプリケーションのサイズが小さくなります。

✔️ SQLite のバグやセキュリティの脆弱性に対する重要な修正プログラムが公開された場合でも、アプリの新しいバージョンをユーザーに勧める必要がありません。 Windows 版の SQLite は、Microsoft が SQLite.org と連携して保守します。

✔️ SQLite の SDK バージョンが既にメモリに読み込まれている可能性が高いため、アプリの読み込み時間が高速になる可能性があります。

まず、DataAccess という名前のプロジェクトにクラスを追加します。 データ アクセス ロジックを他のクライアント コードと共有する予定の場合は、.NET クラス ライブラリ プロジェクトを使用してデータ アクセス コードを含めることができますが、この例では使用しません。

  1. ソリューションを右クリックし、 [ソリューションの NuGet パッケージの管理] をクリックします。

    Visual Studio の [ソリューション エクスプローラー] で、プロジェクトが右クリックされて、[NuGet パッケージの管理] オプションが強調表示されているスクリーンショット。

    この時点で 2 つの選択肢があります。 Windows に含まれている SQLite のバージョンを使用することができます。または、何らかの理由で特定バージョンの SQLite を使用する場合は、パッケージに SQLite ライブラリを含めることができます。 Windows に含まれている SQLite のバージョンを使用します。

  2. [参照] タブを選択し、Microsoft.Data.SQLite パッケージを検索して、最新の安定バージョンをインストールします。

    SQLite NuGet パッケージ

SQLite データベースのデータの追加と取得

以下の作業を行います。

1️⃣ データ アクセス クラスを準備します。

2️⃣ SQLite データベースを初期化します。

3️⃣ SQLite データベースにデータを挿入します。

4️⃣ SQLite データベースからデータを取得します。

5️⃣ 基本的なユーザー インターフェイスを追加します。

データ アクセス クラスを準備する

プロジェクトで DataAccess クラスを開き、そのクラスを静的に設定します。

注意

この例ではデータ アクセス コードを静的クラスに配置しますが、これは設計上の選択肢であり、完全に省略可能です。

public static class DataAccess
{
}

このファイルの先頭に、次の using ステートメントを追加します。

using Microsoft.Data.Sqlite;
using System.Collections.Generic;

SQLite データベースを初期化する

DataAccess クラスに、SQLite データベースを初期化するメソッドを追加します。

public async static void InitializeDatabase()
{ 
    await ApplicationData.Current.LocalFolder
            .CreateFileAsync("sqliteSample.db", CreationCollisionOption.OpenIfExists);
    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path,
                                 "sqliteSample.db");
    using (var db = new SqliteConnection($"Filename={dbpath}"))
    {
        db.Open();

        string tableCommand = "CREATE TABLE IF NOT " +
            "EXISTS MyTable (Primary_Key INTEGER PRIMARY KEY, " +
            "Text_Entry NVARCHAR(2048) NULL)";

        var createTable = new SqliteCommand(tableCommand, db);

        createTable.ExecuteReader();
    }
}

注意

ApplicationData メンバーを使用する上記のコードは、アプリ コンテナーで実行されているパッケージ アプリでのみ機能します。 他のすべての Windows アプリは、ApplicationData クラス経由で メンバーにアクセスする必要があります。

このコードは、SQLite データベースを作成し、アプリケーションのローカル データ ストアに保存します。

この例では、データベースに sqlliteSample.db という名前を付けますが、インスタンス化するすべての SqliteConnection オブジェクトでその名前を使用する限り、任意の名前を使用することができます。 運用アプリケーションでは、データベース ファイル名などの接続情報は、ハードコーディングせずにアプリ構成に格納する必要があります (「Visual Studio 接続済みサービスを使用して Azure App Configuration を追加する」を参照してください)。

プロジェクトの App.xaml.cs ファイルのコンストラクターで、InitializeDatabase クラスの DataAccess メソッドを呼び出します。 これにより、アプリが起動するたびにデータベースが作成されるか、開かれます。

public App()
{
    this.InitializeComponent();

    DataAccess.InitializeDatabase();
}

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

DataAccess クラスに、SQLite データベースにデータを挿入するメソッドを追加します。 このコードでは、クエリでパラメーターを使用して SQL インジェクション攻撃を防ぎます。

public static void AddData(string inputText)
{
    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path,
                                 "sqliteSample.db");
    using (var db = new SqliteConnection($"Filename={dbpath}"))
    {
        db.Open();

        var insertCommand = new SqliteCommand();
        insertCommand.Connection = db;

        // Use parameterized query to prevent SQL injection attacks
        insertCommand.CommandText = "INSERT INTO MyTable VALUES (NULL, @Entry);";
        insertCommand.Parameters.AddWithValue("@Entry", inputText);

        insertCommand.ExecuteReader();
    }

}

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

SQLite データベースの表からデータのすべての行を取得するメソッドを追加します。

public static List<string> GetData()
{
    var entries = new List<string>();
    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path,
                                 "sqliteSample.db");
    using (var db = new SqliteConnection($"Filename={dbpath}"))
    {
        db.Open();
        var selectCommand = new SqliteCommand
            ("SELECT Text_Entry from MyTable", db);

        SqliteDataReader query = selectCommand.ExecuteReader();

        while (query.Read())
        {
            entries.Add(query.GetString(0));
        }
    }

    return entries;
}

Read メソッドは、返されるデータの行を次に進めます。 このメソッドでは、残りの行がある場合は true を返し、ない場合は false を返します。

GetString メソッドは、指定された列の値を文字列として返します。 このメソッドでは、必要なデータの 0 から始まる列の序数を表す整数値を受け取ります。 GetDataTimeGetBoolean などの同様のメソッドを使用できます。 列に格納するデータの型に基づいてメソッドを選択します。

この例では 1 つの列のすべてのエントリを選択しているため、序数パラメーターがそれほど重要ではありません。 ただし、クエリに複数の列が含まれる場合は、序数値を使用してデータを取り出す列を取得します。

基本的なユーザー インターフェイスを追加する

プロジェクトの MainWindow.xaml ファイルに、次の XAML を追加します。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBox x:Name="Input_Box"/>
        <Button Click="AddData">Add</Button>
        <ListView x:Name="Output">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Grid>

この基本的なユーザー インターフェイスでは、SQLite データベースに追加する文字列を入力するための TextBox をユーザーに提供します。 この UI の Button を、SQLite データベースからデータを取得して、ListView にそのデータを表示するイベント ハンドラーに接続します。

MainWindow.xaml.cs ファイルに、次のハンドラーを追加します。 これは、UI で ClickButton イベントに関連付けたメソッドです。

private void AddData(object sender, RoutedEventArgs e)
{
    DataAccess.AddData(Input_Box.Text);

    Output.ItemsSource = DataAccess.GetData();
}

アプリケーションの起動時に既存のデータが読み込まれることを確認する必要もあります。 MainWindow コンストラクターに、GetData() を呼び出すコード行を追加します。

public MainWindow()
{
    this.InitializeComponent();

    Output.ItemsSource = DataAccess.GetData();
}

これで終了です。 Microsoft.Data.Sqlite を参照して、他に SQLite データベースと連携できるものを確認してください。 Windows アプリでデータを使用するその他の方法については、以下のリンクを参照してください。

SQL インジェクション攻撃を回避する

この例のコードでは、パラメーター化されたクエリを使用して SQL インジェクション攻撃を防ぎます。 ユーザー入力を SQL クエリ文字列に連結しないでください。 常にパラメーターを使用します。 SQL インジェクション攻撃の回避に関するその他のヒントについては、Copilot にお問い合わせください。

次のテキストは Copilot のプロンプトの例を示しています。

Can you provide some best practices to avoid SQL injection attacks when writing SQLite queries in C# code?

Copilot では AI を利用しているため、想定外のことや間違いが起こる可能性があります。 詳細については、 Copilot に関する FAQ を参照してください。

アプリを SQL Server データベースに直接接続する

Windows アプリでの SQL Server データベースの使用」をご覧ください。

異なるプラットフォームにわたる異なるアプリの間でコードを共有する

デスクトップと UWP 間のコード共有に関するページをご覧ください。

Azure SQL バックエンドでマスター/詳細ページを追加する

顧客注文データベースのサンプルをご覧ください。