プログラム 技術

C#のSQLCommandをクラス化してみる

以前、C#を使ってSQLに様々な方法でアクセスする方法を紹介しましたが、今回はその中でもSQLCommandをある程度使いやすいようにクラス化したものを共有します
また、今回は『System.Data.SqlClient』ではなく、『Microsoft.Data.SqlClient』を使用していますがどちらでも問題なく動作すると思います
※『System.Data.SqlClient』は本記事のC#バージョンだと非推奨になっているため

名称バージョン
C#.Net 8.0
Microsoft.Data.SqlClient6.0.1
関連記事
SQLServerにC#でアクセスする(SqlCommand版) - ナストンのまとめ
SQLServerにC#でアクセスする(SqlCommand版) - ナストンのまとめ

これまでSQLサーバーにC#でアクセスしたことがなく、そのやり方を勉強した際に使用したものです。今回はSQLComman ...

記事へ

接続

まず初めにコンストラクタの引数で受け取った値を使用してSQLに接続します

public SqlDataAccess(string sqlServerName, string dbName, bool persistSecurityInfo, string connectUserID, string password, int timeOut = 30, bool useTransaction = false)
{
    _timeOut = timeOut;
    string connectionString = BuildConnectionString(sqlServerName, dbName, persistSecurityInfo, connectUserID, password);

    // コネクションを開く
    OpenConnection(connectionString, useTransaction);
}

private string BuildConnectionString(string sqlServerName, string dbName, bool persistSecurityInfo, string connectUserID, string password)
{
    var conn = new SqlConnectionStringBuilder
    {
        DataSource = sqlServerName,
        InitialCatalog = dbName,
        PersistSecurityInfo = persistSecurityInfo,
        TrustServerCertificate = true, // 証明書の検証を行わない
        Encrypt = true, // 暗号化を有効にする
        UserID = connectUserID,
        Password = password,
        ConnectTimeout = _timeOut
    };

    return conn.ConnectionString;
}

public void OpenConnection(string connectionString, bool useTransaction)
{
    _connection = new SqlConnection(connectionString);
    _connection.Open();

    _useTransaction = useTransaction;

    if (useTransaction)
    {
        _transaction = _connection.BeginTransaction();
    }
}

使い方としては以下のようになります

string sqlServerName = "your_sql_server_name";
string dbName = "your_database_name";
string userID = "your_user_id";
string password = "your_password";

using (var sqlDataAccess = new SqlDataAccess(sqlServerName, dbName, true, userID, password))
{
    // ここに処理をSQLへの書く
}

情報の取得

次に情報の取得ですが、内容としてはSQL文を実行してその結果をActionとして返却しています

public void ExecuteReader(string sqlText, List<SqlParameter> parameters = null, Action<SqlDataReader> readAction = null)
{
    try
    {
        using (var command = _connection.CreateCommand())
        {
            if (_useTransaction)
            {
                command.Transaction = _transaction;
            }

            command.CommandText = sqlText;
            command.CommandTimeout = _timeOut;

            if (parameters != null)
            {
                command.Parameters.AddRange(parameters.ToArray());
            }

            using (var reader = command.ExecuteReader())
            {
                readAction?.Invoke(reader);
            }
        }
    }
    catch
    {
        if (_transaction != null)
        {
            _doneRollback = true;
        }
        throw;
    }
}

実際に使用する場合は、以下のようになります

string selectQuery = $"SELECT * FROM {tableName}";
sqlDataAccess.ExecuteReader(selectQuery, null, reader =>
{
    while (reader.Read())
    {
        Console.WriteLine($"Name: {reader["Name"]}, Age: {reader["Age"]}");
    }
});

値の登録・更新

public int ExecuteNonQuery(string sqlText, List<SqlParameter> parameters = null)
{
    try
    {
        using (var command = _connection.CreateCommand())
        {
            if (_useTransaction)
            {
                command.Transaction = _transaction;
            }

            // SQLコマンドの設定
            command.CommandText = sqlText;

            command.CommandTimeout = _timeOut;

            // パラメータの設定
            if (parameters != null)
            {
                command.Parameters.AddRange(parameters.ToArray());
            }

            var result = command.ExecuteNonQuery();
            command.Parameters.Clear();

            return result;
        }
    }
    catch
    {
        if (_transaction != null)
        {
            _doneRollback = true;
        }
        throw;
    }
}

実際に使用する場合は、以下のようになります

string insertQuery = $"INSERT INTO {tableName} (Name, Age, ModifiedDate) VALUES (@Value1, @Value2, SYSDATETIME())";
var insertParameters = new List<SqlParameter>
        {
            new SqlParameter("@Value1", "Test001"),
            new SqlParameter("@Value2", "12")
        };
int rowsAffected = sqlDataAccess.ExecuteNonQuery(insertQuery, insertParameters);
Console.WriteLine($"Rows affected by insert: {rowsAffected}");

最後に

今回紹介したものはusing内で実行することを前提としており、トランザクションを使用する場合はSQLに対するすべての処理が正常に完了した場合にのみ変更するようにしています
上記で記載したコードの使い方に関してはGitHubにアップしているので参考にしてみてください

サンプルコード
BlogSampleCodeProjects/TryClass_SqlCommand at main · nasuton/BlogSampleCodeProjects · GitHub
BlogSampleCodeProjects/TryClass_SqlCommand at main · nasuton/BlogSampleCodeProjects · GitHub

Project for sample code used in the blog.(Blogで記載しているサンプルコード ...

GitHubへ

会社紹介

私が所属しているアドバンスド・ソリューション株式会社(以下、ADS)は一緒に働く仲間を募集しています

会社概要
「技術」×「知恵」=顧客課題の解決・新しい価値の創造

この方程式の実現はADSが大切にしている考えで、技術を磨き続けるgeekさと、顧客を思うloveがあってこそ実現できる世界観だと思っています
この『love & geek』の精神さえあれば、得意不得意はno problem!
技術はピカイチだけど顧客折衝はちょっと苦手。OKです。技術はまだ未熟だけど顧客と知恵を出し合って要件定義するのは大好き。OKです
凸凹な社員の集まり、色んなカラーや柄の個性が集まっているからこそ、常に新しいソリューションが生まれています

ミッション
私たちは、テクノロジーを活用し、業務や事業の生産性向上と企業進化を支援します

ホームページ
アドバンスド・ソリューション株式会社|ADS Co., Ltd.
アドバンスド・ソリューション株式会社|ADS Co., Ltd.

Microsoft 365/SharePoint/Power Platform/Azure による DX コンサル・シス ...

サイトへ移動

PR

-プログラム, 技術
-,