はじめに
業務システムの開発において、共通処理の記述や大容量データの扱いには常に「保守性」と「パフォーマンス」の課題がつきまといます。
今回は、開発中に直面した具体的な課題とその解決策を、備忘録を兼ねてまとめました。
1. jQuery:DOM構造に依存しない安全な要素選択
課題
$(this).parents('div').parents('div') のように階層を固定して親要素を辿ると、HTMLのデザイン(divの追加など)が少し変わっただけでコードが壊れてしまいます。また、モーダル画面などの共通処理では、意図せず背景(親画面)の要素まで操作してしまう事故が発生します。
解決策:.closest() を活用する
特定のクラス名(モーダルの枠など)を指定して遡ることで、構造の変化に強く、かつ操作範囲を限定した安全なコードになります。
// ❌ 壊れやすく、範囲が広すぎる
$(this).parents('form').parents('div').parents('div').find(".target").remove();
// ⭕ 保守性が高く、操作範囲も限定される
// 「一番近いモーダルの枠」の中だけで要素を探す
$(this).closest('.modal-content').find(".target").remove();
2. C# × SQL:安全で読みやすいデータ取得
課題
string.Format でSQLを組み立てると、SQLインジェクションの脆弱性が生まれるだけでなく、日付フォーマットの不整合によるエラーの原因になります。
解決策:パラメータ化クエリと前置カンマ
セキュリティを担保しつつ、SQL自体の可読性も高めます。
- 前置カンマ: 行の入れ替えやコメントアウトが容易になり、保守性が向上します。
- SqlParameter: 型の安全性を確保し、インジェクションを防止します。
-- 先頭カンマで視認性向上
SELECT
ID
, Name
, Price
FROM Table
WHERE TargetDate BETWEEN @from AND @to
// ⭕ SQLパラメータを使用して安全に実行
cmd.CommandText = sql;
cmd.Parameters.Add(new SqlParameter("@from", SqlDbType.DateTime) { Value = fromDate });
cmd.Parameters.Add(new SqlParameter("@to", SqlDbType.DateTime) { Value = toDate });
3. ASP.NET:大容量CSV出力を支えるストリーミング
課題
数万件を超えるデータのCSVダウンロードでは、サーバーのメモリ不足やタイムアウトが問題になります。
解決策:Response.BufferOutput = false
データをメモリに溜め込まず、準備ができた行から順次送り出す「ストリーミング出力」を採用します。
// 1. バッファリングを無効化(逐次出力モード)
Response.BufferOutput = false;
// 2. Shift-JIS (CP932) で書き出し
// Excel等での文字化けを防ぐためEncoding 932を指定
using (var writer = new StreamWriter(response.OutputStream, Encoding.GetEncoding(932), 1024 * 64))
{
// 3. ループ内で1行ずつ書き込む
// 書き込んだそばからクライアントへデータが送信される
foreach (var row in dataList) {
writer.WriteLine(convertToCsv(row));
}
}
ストリーミングのメリット
- メモリ節約: 1GBのファイルでも、数KBのバッファで送信可能。
- レスポンス性: ユーザー側のダウンロードが即座に開始されるため、UXが向上。
まとめ
-
jQuery:
closest()で「意味のある親」を狙い、DOMの変化に備える。 - SQL: パラメータ化を徹底し、インジェクションと型エラーを防ぐ。
-
出力:
BufferOutput = falseで大容量データもスマートに捌く。
少しの工夫で、バグの少ない、そしてユーザーに優しいシステムを目指しましょう。