1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C#】ラップ型クラスを使って例外が発生した場合の処理を返却する方法

Posted at

概要

コンソールアプリでデータベース接続情報もしくは検索値が正常または異常な場合の処理を動的に表示させる方法を作ってみました。

もうちょっと具体的にどんなものを作ったの?

下記の従業員テーブルから従業員IDemployeeIdを検索キーにして一意の従業員情報を取得する方法で、
返却される値は、3パターンを考えてみました。

 サーバ名   DB名   従業員ID   返却値 
 正常値   正常値   DBに存在する   ラップ型エンティティクラスに従業員情報を格納 
 正常値   正常値   DBに存在しない   ラップ型エンティティクラスにNULLを格納 
 異常値   異常値   DBに存在する   ラップ型エンティティクラスにエラーコードを格納 

image.png

戻り値をエンティティにすると、例外エラーexceptionが発生した場合どうするの?というケースが発生するので
ラップ型クラスを採用すrことにしました。

このラップ型クラスは、エンティティに加えて例外エラーといった付随情報も戻り値として返却されることができる拡張性の高い技術です。

ディレクトリ

└── ConsoleAppSQLServer/
    ├── 依存関係/
    │   └── パッケージ/
    │       └── System.Data.SqlClient(4.9.0)
    ├── Entity/
    │   └── EmployeeEntity.cs
    ├── Program.cs
    └── ResultWrapper.cs

サンプルソース

Program.cs
using System;
using System.Configuration;
using ConsoleAppSQLServer.Entity;
using System.Data.SqlClient;

namespace ConsoleAppSQLServer
{
    class Program
    {
        private const int ERR_SQL_EXCEPTION = -97;
        private const int ERR_EXCEPTION = -99;
        public static void Main()
        {
            ResultWrapper<EmployeeEntity> entity = GetEmployeeEntity();
            // 結果をチェックしてコンソールに出力
            if (entity.ErrorCode == -97) 
            {
                Console.WriteLine("データベース接続に失敗しました。");
                return;
            }
            if (entity.ErrorCode == -99) 
            {
                Console.WriteLine("予期せぬエラーです。");
                return ;
            }

            if (entity.Value == null) 
            {
                Console.WriteLine("データがありません。");
                return;
            }

            Console.WriteLine($"従業員IDは{entity.Value.EmployeeId}で、従業員名は{entity.Value.Name}です。");
        }

        public static ResultWrapper<EmployeeEntity> GetEmployeeEntity() 
        {
            Console.Write("最初に、サーバ名を入力してください。");
            string serverName = Console.ReadLine();

            Console.Write("次に。データベース名を入力してください。");
            string databaseName = Console.ReadLine();
            
            //データベース情報
            string connectionString = $"Server={serverName};Database={databaseName};Integrated Security=true";

            Console.Write("最後に、検索したい従業員IDを入力してください。");
            int inputEmployeeId = int.Parse(Console.ReadLine());

            string query = "SELECT employeeId,name FROM [test].[dbo].[employee] WHERE employeeId = @employeeId";

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                try
                {
                    connection.Open();
                    using (SqlCommand command = new SqlCommand(query, connection))
                    {
                        command.Parameters.Add("@employeeId", System.Data.SqlDbType.Int).Value = inputEmployeeId;
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            // データが存在するか確認
                            if (reader.Read())
                            {
                                // EmployeeEntityのインスタンスを作成し、データを割り当てる
                                EmployeeEntity employeeEntity = new EmployeeEntity
                                {
                                    // カラム名を指定してデータを取得
                                    EmployeeId = reader.GetInt32(reader.GetOrdinal("employeeId")),
                                    Name = reader.GetString(reader.GetOrdinal("name"))
                                };
                                return ResultWrapper<EmployeeEntity>.Success(employeeEntity);
                            }
                            else
                            {
                                // データが見つからない場合
                                return ResultWrapper<EmployeeEntity>.Success(null);
                            }
                        }
                    }
                    
                }
                catch (SqlException sqlException)
                {
                    return ResultWrapper<EmployeeEntity>.Failure(ERR_SQL_EXCEPTION);
                }
                catch (Exception exception) 
                {
                    return ResultWrapper<EmployeeEntity>.Failure(ERR_EXCEPTION);
                }
                
            }
        }
    }
}

EmployeeEntity.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAppSQLServer.Entity
{
    public class EmployeeEntity
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
    }
}

ResultWrapper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAppSQLServer
{
    public class ResultWrapper<T>
    {
        public bool IsSuccess { get; }
        public T Value { get; }
        public int ErrorCode { get; }

        private ResultWrapper(T value,bool isSuccess,int errorCode) 
        {
            IsSuccess = isSuccess;
            Value = value;
            ErrorCode = errorCode; 
        }

        // 成功の時の静的メソッド
        public static ResultWrapper<T> Success(T value) 
        {
            return new ResultWrapper<T>(value,true,0);
        }

        // 失敗の時の静的メソッド
        public static ResultWrapper<T> Failure(int errorCode) 
        {
            return new ResultWrapper<T>(default,false,errorCode);
        }
    }
}

サイト

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?