WinForms と SQLite で作る Person 管理アプリケーション ~ チュートリアル

1. はじめに

このチュートリアルでは、WinForms アプリケーション内で SQLite データベースを利用し、氏名(Name)と電話番号(PhoneNumber)のプロパティを持つ Person クラスのデータを管理する方法を解説します。
具体的には、以下の内容を扱います。

  • Person クラスの作成
    氏名と電話番号を保持するシンプルなモデルクラスを作成します。
  • DataAccess クラスの実装
    SQLite データベースの初期化、データの追加、一覧取得、削除、全削除の各処理を実装します。
  • Form1 の実装
    DataGridView を利用してデータを表示し、テキストボックスとボタンでデータの追加、削除、全削除を実行するフォームを作成します。

2. 必要な環境

  • Visual Studio (C# 開発環境)
  • .NET Framework または .NET Core の WinForms プロジェクト
  • NuGet パッケージ Microsoft.Data.Sqlite のインストール
  • NeGetパッケージUno.UIのインストール

このサンプルはテンプレートとして、Windows フォームアプリ(.NET)で作成していますが、Windows フォームアプリケーション(.NET Framework)でも動作します


3. Person クラスの作成

まず、データモデルとして Person クラスを作成します。
このクラスは、各レコードの識別子(Id)、氏名(Name)、電話番号(PhoneNumber)のプロパティを持ちます。

namespace SQLitePlayerClassSample
{
    class Person
    {
        public int Id { get; set; }           // 自動採番される主キー
        public string Name { get; set; }      // 氏名
        public string PhoneNumber { get; set; } // 電話番号

    }
}

4. DataAccess クラスの実装

次に、SQLite データベースとのやり取りを行う DataAccess クラスを作成します。
このクラスでは、以下の操作を実装します。

  • データベース・テーブルの初期化
    Persons テーブルが存在しない場合は作成する。
  • データの追加
    Person オブジェクトの情報をテーブルに追加する。
  • データの一覧取得
    テーブル内の Person 情報を List<Person> として取得する。
  • 特定レコードの削除
    選択された Person を Id をキーに削除する。
  • 全データの削除
    Persons テーブル内のすべてのレコードを削除する。
using Microsoft.Data.Sqlite;
using Windows.Storage;

namespace SQLitePlayerClassSample
{
    class DataAccess
    {
        // データベースと Persons テーブルの初期化(テーブルが存在しなければ作成)
        public async static Task InitializeDatabaseAsync()
        {
            await ApplicationData.Current.LocalFolder.
                CreateFileAsync("sqlitePersons.db", CreationCollisionOption.OpenIfExists);
            // データベースファイルのパス(Persons 情報用)
            string dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqlitePersons.db");

            using (var db = new SqliteConnection($"Filename={dbPath}"))
            {
                db.Open();
                string tableCommand = "CREATE TABLE IF NOT EXISTS Persons (" +
                                      "Id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                                      "Name NVARCHAR(100) NOT NULL, " +
                                      "PhoneNumber NVARCHAR(50) NOT NULL)";
                using (var createTable = new SqliteCommand(tableCommand, db))
                {
                    createTable.ExecuteNonQuery();
                }
            }
        }

        // Person 情報の追加
        public static void AddPerson(Person person)
        {
            // データベースファイルのパス(Persons 情報用)
            string dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqlitePersons.db");
            using (var db = new SqliteConnection($"Filename={dbPath}"))
            {
                db.Open();
                string insertCommand = "INSERT INTO Persons (Name, PhoneNumber) VALUES (@Name, @PhoneNumber)";
                using (var command = new SqliteCommand(insertCommand, db))
                {
                    command.Parameters.AddWithValue("@Name", person.Name);
                    command.Parameters.AddWithValue("@PhoneNumber", person.PhoneNumber);
                    command.ExecuteNonQuery();
                }
            }
        }

        // Person 情報の一覧を取得
        public static List<Person> GetPersons()
        {
            var persons = new List<Person>();
            // データベースファイルのパス(Persons 情報用)
            string dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqlitePersons.db");
            using (var db = new SqliteConnection($"Filename={dbPath}"))
            {
                db.Open();
                string selectCommand = "SELECT Id, Name, PhoneNumber FROM Persons";
                using (var command = new SqliteCommand(selectCommand, db))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            persons.Add(new Person()
                            {
                                Id = reader.GetInt32(0),
                                Name = reader.GetString(1),
                                PhoneNumber = reader.GetString(2)
                            });
                        }
                    }
                }
            }
            return persons;
        }

        // 指定した Person を削除(ここでは Id をキーに削除)
        public static void DeletePerson(int personId)
        {
            // データベースファイルのパス(Persons 情報用)
            string dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqlitePersons.db");

            using (var db = new SqliteConnection($"Filename={dbPath}"))
            {
                db.Open();
                string deleteCommand = "DELETE FROM Persons WHERE Id = @Id";
                using (var command = new SqliteCommand(deleteCommand, db))
                {
                    command.Parameters.AddWithValue("@Id", personId);
                    command.ExecuteNonQuery();
                }
            }
        }

        // Persons テーブル内の全データをクリア(テーブル自体は残す)
        public static void ClearPersons()
        {
            // データベースファイルのパス(Persons 情報用)
            string dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqlitePersons.db");

            using (var db = new SqliteConnection($"Filename={dbPath}"))
            {
                db.Open();
                string deleteAll = "DELETE FROM Persons";
                using (var command = new SqliteCommand(deleteAll, db))
                {
                    command.ExecuteNonQuery();
                }
            }
        }
    }
}

5. Form1 クラスの実装

最後に、フォーム側のコードを作成します。
このサンプルでは、以下のコントロールを利用します。

  • DataGridView (dataGridView1)
    登録された Person 情報の一覧を表示します。
  • TextBox (txtName)
    氏名の入力用。
  • TextBox (txtPhone)
    電話番号の入力用。
  • Button (btnAdd)
    Person の追加処理を実行します。
  • Button (btnDelete)
    DataGridView で選択された Person の削除を実行します。
  • Button (btnClear)
    Persons テーブル内の全データをクリアします。

以下は、フォームのコード例です。

namespace SQLitePlayerClassSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // フォーム起動時にデータベース初期化& DataGridView の更新
            InitializeDatabaseAndLoadData();
        }

        // 非同期でデータベース初期化& DataGridView のデータ読み込み
        private async void InitializeDatabaseAndLoadData()
        {
            await DataAccess.InitializeDatabaseAsync();
            LoadDataIntoDataGridView();
        }

        // DataGridView に Persons テーブルの情報を読み込む
        private void LoadDataIntoDataGridView()
        {
            var persons = DataAccess.GetPersons();
            dataGridView1.DataSource = persons;
        }

        // 「追加」ボタンのイベントハンドラ:入力された氏名と電話番号を Person として追加
        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(txtName.Text) && !string.IsNullOrWhiteSpace(txtPhone.Text))
            {
                Person person = new Person()
                {
                    Name = txtName.Text,
                    PhoneNumber = txtPhone.Text
                };
                DataAccess.AddPerson(person);
                LoadDataIntoDataGridView();
                txtName.Clear();
                txtPhone.Clear();
            }
            else
            {
                MessageBox.Show("氏名と電話番号を入力してください。");
            }
        }

        // 「削除」ボタンのイベントハンドラ:DataGridView で選択された行の Person を削除
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count > 0)
            {
                // 複数行選択可能な場合、最初の行を対象とする例です
                var row = dataGridView1.SelectedRows[0];
                if (row.DataBoundItem is Person person)
                {
                    DataAccess.DeletePerson(person.Id);
                    LoadDataIntoDataGridView();
                }
            }
            else
            {
                MessageBox.Show("削除する行を選択してください。");
            }
        }

        // 「全削除」ボタンのイベントハンドラ:Persons テーブル内の全データをクリア
        private void btnClear_Click(object sender, EventArgs e)
        {
            DataAccess.ClearPersons();
            LoadDataIntoDataGridView();
            MessageBox.Show("すべてのデータを削除しました。");
        }
    }
}

6. まとめ

今回のチュートリアルでは、WinForms アプリケーションで SQLite を利用して、氏名と電話番号を管理する Person クラスのデータを扱う方法を学びました。
具体的には、

  • Person クラス を作成してデータモデルを定義
  • DataAccess クラス で SQLite データベースの初期化、追加、取得、削除、全削除の処理を実装
  • Form1 クラス で DataGridView と各ボタンを用いてデータの表示・操作を実現

この基本構造を応用すれば、より複雑なデータ管理システムも構築できます。各自のプロジェクトに合わせた機能拡張や UI 改良に挑戦してみてください。


以上で、WinForms と SQLite を用いた Person 管理アプリケーションのチュートリアルは終了です。