# 送信履歴テーブルNULL値対応実装手順書
## 概要
送信履歴テーブルからデータを取得する際に、特定のカラムがNULLである可能性を考慮した処理を実装します。これにより、送信パターンを使用しない場合などでもエラーが発生せずにデータを取得できるようになります。
## 対象カラムとNULL値の可能性
### NULL値を許可するカラム
1. **送信パターンID** (`int?`)
- 送信パターンを使用しない場合はNULL
2. **送信パターン名称** (`nvarchar(100)`)
- 送信パターンを使用しない場合はNULL
3. **送信パターン定型文** (`nvarchar(max)`)
- 送信パターンを使用しない場合はNULL
4. **送信パターン送信対象** (`int?`)
- 送信パターンを使用しない場合はNULL
5. **送信パターン並び順** (`int?`)
- 送信パターンを使用しない場合はNULL
## 現状の問題点
### SendHistoryDao.cs - GetSendTypeListメソッド (17-69行目)
現在の実装では、`row.Field<T>()`メソッドを使用していますが、int型のカラムに対してNULL値が存在する場合、例外が発生する可能性があります。
```csharp
PatternId = row.Field<int>("送信パターンID"), // NULL値の場合、例外発生
PatternSortOrder = row.Field<int>("送信パターン並び順"), // NULL値の場合、例外発生
```
### SendHistoryDao.cs - GetSendHistoryメソッド (71-118行目)
このメソッドでは既にNULL値の考慮がされていますが、一部の処理が統一されていません。
## 実装手順
### ステップ1: GetSendTypeListメソッドの修正
#### 1.1 NULL値を考慮した実装に変更
```csharp
public List<SendHistoryDto> GetSendTypeList(int type)
{
string sql = $@"
SELECT
*,
CASE
WHEN 送信失敗件数 > 0
THEN 'エラーあり'
ELSE '成功'
END AS '送信結果'
FROM dbo.送信履歴
WHERE 送信タイプ = @type
ORDER BY 送信日時 DESC";
var param = new Dictionary<string, object>
{
{"@type",type }
,
};
DataTable dt = _db.ExecQuery(sql,param);
var list = new List<SendHistoryDto>();
foreach (DataRow row in dt.Rows)
{
var dto = new SendHistoryDto
{
SendHistoryId = row.Field<int>("送信履歴ID"),
SendType = row.Field<int>("送信タイプ"),
SuccessCount = row.Field<int>("送信成功件数"),
FailureCount = row.Field<int>("送信失敗件数"),
SenderApiToken = row.Field<string>("C_APIトークン"),
// NULL値を考慮した実装に変更
PatternId = row["送信パターンID"] != DBNull.Value
? (int?)Convert.ToInt32(row["送信パターンID"])
: null,
PatternName = row.Field<string>("送信パターン名称"),
PatternTemplateText = row.Field<string>("送信パターン定型文"),
PatternTarget = row["送信パターン送信対象"] != DBNull.Value
? (int?)Convert.ToInt32(row["送信パターン送信対象"])
: null,
PatternSortOrder = row["送信パターン並び順"] != DBNull.Value
? (int?)Convert.ToInt32(row["送信パターン並び順"])
: null,
SendContents = row.Field<string>("送信内容"),
RegularDestinationSelectType = (Constants.DESTINAION_SELECT_TYPE)Convert.ToInt32(row["定期送信_送信対象"]),
RegularFolderPath = row.Field<string>("定期送信_添付ファイル管理フォルダパス"),
AdhocHasAttachment = row.Field<bool>("不定期送信_添付ファイル有無"),
AdhocAttachmentFilePath = row.Field<string>("不定期送信_添付ファイルパス"),
SendDt = row.Field<DateTime?>("送信日時"),
SendResults = row.Field<string>("送信結果")
,
};
list.Add(dto);
}
return list;
}
```
### ステップ2: GetSendHistoryメソッドの確認と統一
#### 2.1 現在の実装を確認
GetSendHistoryメソッドは既にNULL値の考慮がされているため、大きな修正は不要です。ただし、コードの一貫性を保つため、以下の点を確認します:
1. すべてのNullable型カラムに対してDBNull.Valueのチェックが行われている
2. 文字列型のカラムに対しては`as string`を使用している
3. 数値型のNullableカラムに対しては適切な変換が行われている
### ステップ3: DTOクラスの確認
#### 3.1 SendHistoryDto.csの確認
DTOクラスでは既に適切なNullable型が定義されています:
```csharp
public int? PatternId { get; set; }
public int? PatternTarget { get; set; }
public int? PatternSortOrder { get; set; }
```
これらの定義は正しいため、変更は不要です。
### ステップ4: 関連する画面の動作確認
#### 4.1 影響を受ける画面
1. **送信履歴一覧画面** - GetSendTypeListメソッドを使用
2. **送信履歴詳細画面** - GetSendHistoryメソッドを使用
3. **送信失敗データ再送機能** - GetSendHistoryメソッドを使用
#### 4.2 NULL値の表示方法
- **PatternName**がNULLの場合:`"<パターン未指定>"`と表示(MessageSendResultControl.cs 89行目で既に実装済み)
- **その他のNULL値**:適切なデフォルト値または空文字列として表示
## テストシナリオ
### シナリオ1: 送信パターンを使用した送信履歴
1. 送信パターンを選択して送信を実行
2. 送信履歴一覧画面でデータが正しく表示されることを確認
3. 詳細画面でパターン情報が正しく表示されることを確認
### シナリオ2: 送信パターンを使用しない送信履歴
1. 送信パターンを選択せずに送信を実行
2. 送信履歴一覧画面でデータが正しく表示されることを確認
3. 詳細画面でパターン名が`"<パターン未指定>"`と表示されることを確認
### シナリオ3: NULL値を含むデータの再送
1. 送信パターンを使用しない送信で失敗データを作成
2. 送信履歴詳細画面から再送ボタンをクリック
3. エラーが発生せずに再送画面が開くことを確認
## エラーハンドリング
### 想定されるエラー
1. **InvalidCastException** - NULL値をint型にキャストしようとした場合
2. **NullReferenceException** - NULL値に対してメソッドを呼び出した場合
### 対処方法
1. すべてのNullableカラムに対してDBNull.Valueのチェックを実施
2. 適切な型変換とデフォルト値の設定
3. エラーログの記録と適切なエラーメッセージの表示
## 実装の注意点
### 1. パフォーマンスへの配慮
- `row.Field<T>()`メソッドは内部でNULLチェックを行うため、文字列型には引き続き使用
- int型のNullableカラムのみ明示的なNULLチェックを実施
### 2. 既存機能への影響
- GetSendTypeListメソッドを使用している箇所の動作確認が必要
- 特に送信履歴一覧画面(SendHistoryDgvControl)での表示を確認
### 3. データベーススキーマとの整合性
- データベースのカラム定義がNULL許可になっていることを確認
- 将来的なスキーマ変更に備えて、柔軟な実装を心がける
## 実装チェックリスト
- [ ] GetSendTypeListメソッドのNULL値対応実装
- [ ] 修正後のコンパイルエラーがないことを確認
- [ ] 送信履歴一覧画面での表示確認
- [ ] 送信履歴詳細画面での表示確認
- [ ] NULL値を含むデータでの再送機能の動作確認
- [ ] 単体テストの実施(NULL値を含むテストケース)
- [ ] 結合テストの実施
- [ ] コードレビューの実施
## 追加の推奨事項
### 1. 単体テストの作成
NULL値を含むテストデータを使用した単体テストを作成することを推奨します。
### 2. ログ出力の追加
NULL値が検出された場合のデバッグログを追加することで、問題の早期発見が可能になります。
### 3. 定数の定義
デフォルト値や表示文字列(例:`"<パターン未指定>"`)を定数として定義することで、保守性が向上します。
## まとめ
この実装により、送信履歴テーブルのNULL値を含むデータを安全に取得・表示できるようになります。特に送信パターンを使用しない送信の履歴も正しく扱えるようになり、システムの柔軟性が向上します。