読者です 読者をやめる 読者になる 読者になる

名前埋め込み型フォーマット

.NET のデータアクセスクラス内で SQL のクエリを組み立てるとき、いつも string.Format を使っています。次のように。

string query = string.Format("SELECT {0}, {1} FROM {2} WHERE {0} = @code",
    CustomerTable.CODE,
    CustomerTable.NAME,
    CustomerTable.TABLE_NAME);

テーブル名や列名が定数で用意してあるので、それを string.Format で埋め込んでいるわけです。でも、クエリの書式に {0} や {1} といった記号が埋め込まれていて、読みにくいですね。長いクエリになると保守が大変そうだ。見やすくできないものでしょうか?

そんなとき、名前付きパラメーターを見て思いつきました。「クエリを見やすくしたい!たとえ速度を犠牲にしても…!」という場合でしか使えませんが、こう書けばいいのでは?

string query = "SELECT :code, :name FROM :table WHERE :code = @code"
    .Replace(":code", CustomerTable.CODE)
    .Replace(":name", CustomerTable.NAME)
    .Replace(":table", CustomerTable.TABLE_NAME);

置き換える文字列の数だけ Replace するので遅くなりますが、少なくともクエリ自体は格段に見やすくなります。
先頭のコロンを入力するのが面倒な人は、次のような拡張メソッドを使うと、少しだけ手間が省けます。

public static class StringExtension
{
    public static string Name(this string format, string name, string value)
    {
        if (Regex.IsMatch(name, "^:") == false)
        {
            // 先頭に : が付いていない場合は付ける
            name = ":" + name;
        }
        return format.Replace(name, value);
    }
}

Dictionay でまとめて渡してもいいかもしれません。あと、別にコロンでなくてもいいです。Ruby みたいに #{} で囲むのもいいですね。