C#でSQLiteを使う:System.Data.SQLiteのインストールから使い方まで

はい、承知いたしました。C#でSQLiteを使う方法について、System.Data.SQLiteのインストールから具体的な使い方までを網羅した詳細な記事を作成します。約5000字で記述します。


C#でSQLiteを使う:System.Data.SQLiteのインストールから使い方まで

はじめに

現代のソフトウェア開発において、軽量でポータブルなデータベースのニーズは高まっています。SQLiteは、そのようなニーズに応える優れた選択肢の一つです。C#でSQLiteを利用するには、System.Data.SQLiteライブラリを使用します。この記事では、System.Data.SQLiteのインストール方法から、基本的なデータベース操作、高度な使い方までを詳しく解説します。

SQLiteとは?

SQLiteは、軽量なディスクベースのデータベースエンジンであり、スタンドアロンのアプリケーション、デバイス、組み込みシステムに適しています。SQLiteはサーバーを必要とせず、データベース全体が単一のファイルに格納されるため、移植性と配布が非常に容易です。

SQLiteの主な特徴:

  • 軽量: 小さなフットプリントで、リソース消費が少ない。
  • サーバーレス: サーバープロセスを必要としない。
  • 自己完結型: 必要なものはすべて一つのファイルに格納される。
  • クロスプラットフォーム: Windows、macOS、Linuxなど、多くのOSで動作する。
  • オープンソース: 自由に利用できる。
  • トランザクション対応: ACID特性(原子性、一貫性、分離性、耐久性)をサポート。

System.Data.SQLiteとは?

System.Data.SQLiteは、C#アプリケーションからSQLiteデータベースにアクセスするためのADO.NETプロバイダです。このライブラリを使用することで、C#のコードからSQLiteデータベースの作成、データの読み書き、トランザクション処理などを簡単に行うことができます。

System.Data.SQLiteのインストール

System.Data.SQLiteをC#プロジェクトにインストールする方法はいくつかあります。

  1. NuGetパッケージマネージャーを使用する方法:

    • Visual Studioでプロジェクトを開きます。
    • ツール > NuGetパッケージマネージャー > パッケージマネージャーコンソール を選択します。
    • パッケージマネージャーコンソールで以下のコマンドを入力し、Enterキーを押します。

    powershell
    Install-Package System.Data.SQLite

    このコマンドは、System.Data.SQLiteの最新版をプロジェクトにインストールします。

  2. NuGetパッケージマネージャーUIを使用する方法:

    • Visual Studioでプロジェクトを開きます。
    • プロジェクト > NuGetパッケージの管理 を選択します。
    • 「参照」タブで「System.Data.SQLite」を検索します。
    • System.Data.SQLiteを選択し、「インストール」ボタンをクリックします。
  3. Visual Studio Marketplaceからダウンロードする方法:

    • Visual Studio MarketplaceでSystem.Data.SQLiteを検索します。
    • 適切なバージョン(x86、x64など)をダウンロードし、インストールします。

注意点:

  • System.Data.SQLiteは、プラットフォーム(x86、x64)に合わせて適切なバージョンを選択する必要があります。
  • Visual Studioの再起動が必要な場合があります。

基本的な使い方:データベースの作成、接続、データの読み書き

System.Data.SQLiteをインストールしたら、C#コードからSQLiteデータベースを操作することができます。

1. データベースの作成と接続

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// データベースファイルのパス
string dbFilePath = “mydatabase.db”;

    // 接続文字列の作成
    string connectionString = $"Data Source={dbFilePath};Version=3;";

    // データベースが存在しない場合は作成
    if (!System.IO.File.Exists(dbFilePath))
    {
        SQLiteConnection.CreateFile(dbFilePath);
        Console.WriteLine("データベースファイルを作成しました。");
    }

    // SQLite接続オブジェクトの作成
    using (SQLiteConnection connection = new SQLiteConnection(connectionString))
    {
        try
        {
            // データベースに接続
            connection.Open();
            Console.WriteLine("データベースに接続しました。");

            // ここでデータベース操作を行う
            // 例:テーブルの作成、データの挿入など

        }
        catch (SQLiteException ex)
        {
            Console.WriteLine($"データベース接続エラー: {ex.Message}");
        }
        finally
        {
            // 接続を閉じる(usingステートメントを使用しているため、明示的なCloseは不要)
            // connection.Close();
            Console.WriteLine("データベース接続を閉じました。");
        }
    }

    Console.ReadKey();
}

}
“`

解説:

  • using System.Data.SQLite;: System.Data.SQLite名前空間をインポートし、SQLite関連のクラスを使用できるようにします。
  • dbFilePath: データベースファイルのパスを定義します。この例では、mydatabase.dbという名前のデータベースファイルを作成します。
  • connectionString: データベースへの接続文字列を定義します。Data Sourceはデータベースファイルのパスを指定し、Version=3はSQLiteのバージョンを指定します。
  • SQLiteConnection.CreateFile(dbFilePath): 指定されたパスにデータベースファイルが存在しない場合、新しいデータベースファイルを作成します。
  • SQLiteConnection: SQLiteデータベースへの接続を表すクラスです。usingステートメントを使用することで、接続が自動的に閉じられるようにします。
  • connection.Open(): データベースに接続します。
  • connection.Close(): データベース接続を閉じます。usingステートメントを使用しているため、明示的に呼び出す必要はありません。
  • try-catch-finally: 例外処理を行います。データベース接続中にエラーが発生した場合、エラーメッセージを表示し、finallyブロックで接続を閉じます。

2. テーブルの作成

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// データベースファイルのパス
string dbFilePath = “mydatabase.db”;

    // 接続文字列の作成
    string connectionString = $"Data Source={dbFilePath};Version=3;";

    // データベースが存在しない場合は作成
    if (!System.IO.File.Exists(dbFilePath))
    {
        SQLiteConnection.CreateFile(dbFilePath);
        Console.WriteLine("データベースファイルを作成しました。");
    }

    // SQLite接続オブジェクトの作成
    using (SQLiteConnection connection = new SQLiteConnection(connectionString))
    {
        try
        {
            // データベースに接続
            connection.Open();
            Console.WriteLine("データベースに接続しました。");

            // テーブル作成のSQLコマンド
            string createTableQuery = @"
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    age INTEGER
                );
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(createTableQuery, connection))
            {
                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("テーブルを作成しました。");
            }

        }
        catch (SQLiteException ex)
        {
            Console.WriteLine($"データベース操作エラー: {ex.Message}");
        }
        finally
        {
            // 接続を閉じる(usingステートメントを使用しているため、明示的なCloseは不要)
            // connection.Close();
            Console.WriteLine("データベース接続を閉じました。");
        }
    }

    Console.ReadKey();
}

}
“`

解説:

  • createTableQuery: テーブルを作成するためのSQLコマンドを定義します。この例では、usersという名前のテーブルを作成します。テーブルには、id(整数型、主キー、自動インクリメント)、name(テキスト型、NOT NULL制約)、age(整数型)の3つのカラムがあります。
  • SQLiteCommand: SQLコマンドを実行するためのクラスです。コンストラクタには、SQLコマンドのテキストと接続オブジェクトを指定します。
  • command.ExecuteNonQuery(): SQLコマンドを実行します。このメソッドは、SELECT文以外のSQLコマンド(INSERT、UPDATE、DELETE、CREATE TABLEなど)を実行するために使用されます。

3. データの挿入

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// データベースファイルのパス
string dbFilePath = “mydatabase.db”;

    // 接続文字列の作成
    string connectionString = $"Data Source={dbFilePath};Version=3;";

    // データベースが存在しない場合は作成
    if (!System.IO.File.Exists(dbFilePath))
    {
        SQLiteConnection.CreateFile(dbFilePath);
        Console.WriteLine("データベースファイルを作成しました。");
    }

    // SQLite接続オブジェクトの作成
    using (SQLiteConnection connection = new SQLiteConnection(connectionString))
    {
        try
        {
            // データベースに接続
            connection.Open();
            Console.WriteLine("データベースに接続しました。");

            // テーブル作成のSQLコマンド
            string createTableQuery = @"
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    age INTEGER
                );
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(createTableQuery, connection))
            {
                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("テーブルを作成しました。");
            }

            // データの挿入のSQLコマンド
            string insertQuery = @"
                INSERT INTO users (name, age) VALUES (@name, @age);
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(insertQuery, connection))
            {
                // パラメータの追加
                command.Parameters.AddWithValue("@name", "John Doe");
                command.Parameters.AddWithValue("@age", 30);

                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("データを挿入しました。");
            }


            // データの挿入のSQLコマンド
            string insertQuery2 = @"
                INSERT INTO users (name, age) VALUES (@name, @age);
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(insertQuery2, connection))
            {
                // パラメータの追加
                command.Parameters.AddWithValue("@name", "Jane Smith");
                command.Parameters.AddWithValue("@age", 25);

                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("データを挿入しました。");
            }

        }
        catch (SQLiteException ex)
        {
            Console.WriteLine($"データベース操作エラー: {ex.Message}");
        }
        finally
        {
            // 接続を閉じる(usingステートメントを使用しているため、明示的なCloseは不要)
            // connection.Close();
            Console.WriteLine("データベース接続を閉じました。");
        }
    }

    Console.ReadKey();
}

}
“`

解説:

  • insertQuery: データを挿入するためのSQLコマンドを定義します。この例では、usersテーブルにnameageの値を挿入します。@name@ageはパラメータプレースホルダであり、実際の値は後で設定します。
  • command.Parameters.AddWithValue(): パラメータプレースホルダに値を設定します。@nameには"John Doe"@ageには30を設定しています。

4. データの読み取り

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// データベースファイルのパス
string dbFilePath = “mydatabase.db”;

    // 接続文字列の作成
    string connectionString = $"Data Source={dbFilePath};Version=3;";

    // データベースが存在しない場合は作成
    if (!System.IO.File.Exists(dbFilePath))
    {
        SQLiteConnection.CreateFile(dbFilePath);
        Console.WriteLine("データベースファイルを作成しました。");
    }

    // SQLite接続オブジェクトの作成
    using (SQLiteConnection connection = new SQLiteConnection(connectionString))
    {
        try
        {
            // データベースに接続
            connection.Open();
            Console.WriteLine("データベースに接続しました。");

            // テーブル作成のSQLコマンド
            string createTableQuery = @"
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    age INTEGER
                );
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(createTableQuery, connection))
            {
                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("テーブルを作成しました。");
            }

            // データの挿入のSQLコマンド
            string insertQuery = @"
                INSERT INTO users (name, age) VALUES (@name, @age);
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(insertQuery, connection))
            {
                // パラメータの追加
                command.Parameters.AddWithValue("@name", "John Doe");
                command.Parameters.AddWithValue("@age", 30);

                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("データを挿入しました。");
            }


            // データの挿入のSQLコマンド
            string insertQuery2 = @"
                INSERT INTO users (name, age) VALUES (@name, @age);
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(insertQuery2, connection))
            {
                // パラメータの追加
                command.Parameters.AddWithValue("@name", "Jane Smith");
                command.Parameters.AddWithValue("@age", 25);

                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("データを挿入しました。");
            }

            // データの読み取りのSQLコマンド
            string selectQuery = @"
                SELECT id, name, age FROM users;
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(selectQuery, connection))
            {
                // SQLデータリーダーの作成
                using (SQLiteDataReader reader = command.ExecuteReader())
                {
                    // データの読み取り
                    while (reader.Read())
                    {
                        int id = reader.GetInt32(0);
                        string name = reader.GetString(1);
                        int age = reader.GetInt32(2);

                        Console.WriteLine($"ID: {id}, Name: {name}, Age: {age}");
                    }
                }
                Console.WriteLine("データを読み込みました。");
            }

        }
        catch (SQLiteException ex)
        {
            Console.WriteLine($"データベース操作エラー: {ex.Message}");
        }
        finally
        {
            // 接続を閉じる(usingステートメントを使用しているため、明示的なCloseは不要)
            // connection.Close();
            Console.WriteLine("データベース接続を閉じました。");
        }
    }

    Console.ReadKey();
}

}
“`

解説:

  • selectQuery: データを読み取るためのSQLコマンドを定義します。この例では、usersテーブルからidnameageのすべてのカラムを読み取ります。
  • SQLiteDataReader: SQLコマンドの実行結果を読み取るためのクラスです。command.ExecuteReader()メソッドで作成します。
  • reader.Read(): 次の行を読み取ります。読み取る行がある場合はtrue、ない場合はfalseを返します。
  • reader.GetInt32(0): 0番目のカラム(id)の値を整数型として読み取ります。
  • reader.GetString(1): 1番目のカラム(name)の値を文字列型として読み取ります。
  • reader.GetInt32(2): 2番目のカラム(age)の値を整数型として読み取ります。

5. データの更新

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// … (データベース接続、テーブル作成、データ挿入は省略)

    // データの更新のSQLコマンド
    string updateQuery = @"
        UPDATE users SET age = @age WHERE name = @name;
    ";

    // SQLiteコマンドオブジェクトの作成
    using (SQLiteCommand command = new SQLiteCommand(updateQuery, connection))
    {
        // パラメータの追加
        command.Parameters.AddWithValue("@name", "John Doe");
        command.Parameters.AddWithValue("@age", 35);

        // SQLコマンドの実行
        int rowsAffected = command.ExecuteNonQuery();
        Console.WriteLine($"{rowsAffected} 行を更新しました。");
    }
}

}
“`

6. データの削除

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// … (データベース接続、テーブル作成、データ挿入は省略)

    // データの削除のSQLコマンド
    string deleteQuery = @"
        DELETE FROM users WHERE name = @name;
    ";

    // SQLiteコマンドオブジェクトの作成
    using (SQLiteCommand command = new SQLiteCommand(deleteQuery, connection))
    {
        // パラメータの追加
        command.Parameters.AddWithValue("@name", "John Doe");

        // SQLコマンドの実行
        int rowsAffected = command.ExecuteNonQuery();
        Console.WriteLine($"{rowsAffected} 行を削除しました。");
    }
}

}
“`

高度な使い方

1. トランザクション処理

トランザクションは、複数のデータベース操作を一つの論理的な作業単位として扱うためのメカニズムです。トランザクションを使用することで、データベースの一貫性を保つことができます。

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// データベースファイルのパス
string dbFilePath = “mydatabase.db”;

    // 接続文字列の作成
    string connectionString = $"Data Source={dbFilePath};Version=3;";

    // データベースが存在しない場合は作成
    if (!System.IO.File.Exists(dbFilePath))
    {
        SQLiteConnection.CreateFile(dbFilePath);
        Console.WriteLine("データベースファイルを作成しました。");
    }

    // SQLite接続オブジェクトの作成
    using (SQLiteConnection connection = new SQLiteConnection(connectionString))
    {
        try
        {
            // データベースに接続
            connection.Open();
            Console.WriteLine("データベースに接続しました。");

            // トランザクションの開始
            using (SQLiteTransaction transaction = connection.BeginTransaction())
            {
                try
                {
                    // コマンドの作成
                    using (SQLiteCommand command = connection.CreateCommand())
                    {
                        command.Transaction = transaction; // トランザクションを設定

                        // データの挿入1
                        command.CommandText = "INSERT INTO users (name, age) VALUES ('Alice', 28)";
                        command.ExecuteNonQuery();

                        // データの挿入2
                        command.CommandText = "INSERT INTO users (name, age) VALUES ('Bob', 32)";
                        command.ExecuteNonQuery();

                        // 例外を発生させてロールバックをテストする(必要に応じてコメントアウト)
                        // throw new Exception("トランザクションをロールバックします");

                        // トランザクションのコミット
                        transaction.Commit();
                        Console.WriteLine("トランザクションをコミットしました。");
                    }
                }
                catch (Exception ex)
                {
                    // トランザクションのロールバック
                    transaction.Rollback();
                    Console.WriteLine($"トランザクションをロールバックしました。エラー: {ex.Message}");
                }
            }
        }
        catch (SQLiteException ex)
        {
            Console.WriteLine($"データベース操作エラー: {ex.Message}");
        }
        finally
        {
            // 接続を閉じる(usingステートメントを使用しているため、明示的なCloseは不要)
            // connection.Close();
            Console.WriteLine("データベース接続を閉じました。");
        }
    }

    Console.ReadKey();
}

}
“`

解説:

  • connection.BeginTransaction(): トランザクションを開始します。
  • transaction.Commit(): トランザクションをコミットします。コミットされたトランザクションは、データベースに永続的に保存されます。
  • transaction.Rollback(): トランザクションをロールバックします。ロールバックされたトランザクションは、データベースに反映されません。
  • command.Transaction = transaction;: SQLiteCommandにトランザクションを設定することで、コマンドがトランザクションの一部として実行されるようにします。

2. パラメータ化されたクエリの使用

SQLインジェクション攻撃を防ぐために、パラメータ化されたクエリを使用することを強く推奨します。パラメータ化されたクエリを使用すると、SQLコマンドに直接値を埋め込むのではなく、プレースホルダを使用して値を設定します。

“`csharp
using System.Data.SQLite;

public class SQLiteExample
{
public static void Main(string[] args)
{
// データベースファイルのパス
string dbFilePath = “mydatabase.db”;

    // 接続文字列の作成
    string connectionString = $"Data Source={dbFilePath};Version=3;";

    // データベースが存在しない場合は作成
    if (!System.IO.File.Exists(dbFilePath))
    {
        SQLiteConnection.CreateFile(dbFilePath);
        Console.WriteLine("データベースファイルを作成しました。");
    }

    // SQLite接続オブジェクトの作成
    using (SQLiteConnection connection = new SQLiteConnection(connectionString))
    {
        try
        {
            // データベースに接続
            connection.Open();
            Console.WriteLine("データベースに接続しました。");

            // テーブル作成のSQLコマンド
            string createTableQuery = @"
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    age INTEGER
                );
            ";

            // SQLiteコマンドオブジェクトの作成
            using (SQLiteCommand command = new SQLiteCommand(createTableQuery, connection))
            {
                // SQLコマンドの実行
                command.ExecuteNonQuery();
                Console.WriteLine("テーブルを作成しました。");
            }

            // パラメータ化されたクエリを使用してデータを挿入
            string insertQuery = "INSERT INTO users (name, age) VALUES (@name, @age)";
            using (SQLiteCommand command = new SQLiteCommand(insertQuery, connection))
            {
                command.Parameters.AddWithValue("@name", "Alice");
                command.Parameters.AddWithValue("@age", 30);
                command.ExecuteNonQuery();
                Console.WriteLine("データを挿入しました (Alice)。");
            }

            // パラメータ化されたクエリを使用してデータを検索
            string selectQuery = "SELECT id, name, age FROM users WHERE age > @age";
            using (SQLiteCommand command = new SQLiteCommand(selectQuery, connection))
            {
                command.Parameters.AddWithValue("@age", 25);
                using (SQLiteDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Console.WriteLine($"ID: {reader.GetInt32(0)}, Name: {reader.GetString(1)}, Age: {reader.GetInt32(2)}");
                    }
                }
                Console.WriteLine("データを検索しました。");
            }
        }
        catch (SQLiteException ex)
        {
            Console.WriteLine($"データベース操作エラー: {ex.Message}");
        }
        finally
        {
            // 接続を閉じる(usingステートメントを使用しているため、明示的なCloseは不要)
            // connection.Close();
            Console.WriteLine("データベース接続を閉じました。");
        }
    }

    Console.ReadKey();
}

}
“`

解説:

  • command.Parameters.AddWithValue(): パラメータプレースホルダに値を安全に設定します。

3. 接続プーリング

接続プーリングは、データベース接続を再利用することで、接続の確立にかかるオーバーヘッドを削減する技術です。System.Data.SQLiteは、デフォルトで接続プーリングをサポートしています。

接続プーリングを有効にするには、接続文字列にPooling=Trueを追加します。

csharp
string connectionString = $"Data Source=mydatabase.db;Version=3;Pooling=True;";

4. 暗号化

System.Data.SQLiteは、SQLiteデータベースの暗号化をサポートしています。暗号化を使用することで、データベースファイルの内容を保護することができます。

暗号化を有効にするには、接続文字列にPasswordパラメータを追加します。

csharp
string connectionString = $"Data Source=mydatabase.db;Version=3;Password=mypassword;";

注意点:

  • 暗号化されたデータベースにアクセスするには、正しいパスワードが必要です。
  • パスワードを忘れた場合、データベースの内容を復号化することはできません。

まとめ

この記事では、C#でSQLiteを使用するためのSystem.Data.SQLiteライブラリのインストールから、基本的なデータベース操作、高度な使い方までを詳しく解説しました。System.Data.SQLiteを使用することで、C#アプリケーションからSQLiteデータベースを簡単に操作することができます。

SQLiteは、軽量でポータブルなデータベースであり、小規模なアプリケーションや組み込みシステムに適しています。System.Data.SQLiteを使用することで、C#開発者はSQLiteの利点を最大限に活用することができます。

この記事は、System.Data.SQLiteの基本的な使い方から高度な使い方までを網羅しており、C#開発者がSQLiteを効果的に利用するための包括的なガイドとして役立つはずです。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール