参照系SQL の実行結果をマッピングする型を生成したい

O/R マッパー等のツールを使うと、既存のテーブルやビューなんかは対応するクラスを作成してくれたりしますが、それだけで事足りますか?
個人的には、参照系の処理はクエリ書くかストアド書くか…ってなり、その結果を格納する型も用意しないとダメみたいなパターンが多いです。
まあ、Visual Studio で開発してると自動生成とかしてくれたりするのかな?Entity Framework とか TableAdapter とか。*1
そういうのが使えない環境の場合、クエリも書いて対応する型も書いて…とか面倒じゃね?という事でスクリプトを用意してみました。
Oracle に接続していますが、使う型を変更したら当然 SQL Server でもOKです。
肝は、DbDataAdapter.FillSchema メソッド (System.Data.Common) です。

Main.ps1 ※後(解放)処理とかちゃんと書いてませんので流用する人は気を付けて!

param([String]$connStr, [String]$queryPath)

[void][reflection.assembly]::LoadWithPartialName("System.Data.OracleClient");
$conn = New-Object System.Data.Sql.OracleConnection($connStr);
$query = Get-Content $queryPath -Encoding UTF8
$table = New-Object System.Data.DataTable;
$adapter = New-Object System.Data.OracleClient.OracleDataAdapter($query, $conn);
[void]$adapter.FillSchema($table, [System.Data.SchemaType]::Mapped)

$result = .\Template.ps1 $table.Columns
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.Clipboard]::Clear()
[System.Windows.Forms.Clipboard]::SetData([System.Windows.Forms.DataFormats]::UnicodeText, $result);

Template.ps1

param($columns)
$ConvertName = {
  param($name)
  # 名前の変換処理
  # _の除去とか lowerCamel するとか
  return $name
}
$ConvertType = { 
  param($type) # System.Type が渡ってくる。
  # 型名の変換処理
  # .NET の型と Java の型だと微妙に名前違ったりするよね?
  return $type.ToString()
}
$ret = New-Object System.Text.StringBuilder;
foreach ($column in $columns) {
  $type = & $ConvertType $column.DataType;
  $columnName = $column.columnName;
  $fieldName = & $ConvertName $columnName
  # フィールドの生成部分
[void]$ret.Append(@"
    @Column(name="$columnName")
    public $type $fieldName;

"@);
}
return $ret.ToString()

クリップボードを使っているので、PowerShell は -sta (Single Thread Apartment) で起動する必要があります。
Main.ps1 と Template.ps1 は同じフォルダに配置してください。
コマンドプロンプトからでこんな感じで使います。

C:\Users\user>PowerShell -sta -file 〜\Main.ps1 -connStr 〜 -queryPath 〜.sql

これで、クリップボードSQL の結果に対応するフィールドの一覧がコピーされています。
あとは、ソースコードに貼り付けて出来上がり!
テンプレートは適当にカスタムしたら、好みのフォーマットで出力出来そうです。
簡易なテンプレートなら、PowerShell で十分ですね!


注意点として既に PowerShell を使っている方はご存じでしょうが、デフォルトではスクリプトファイルを実行出来る権限が付与されていません。
ExecutePolicy を使用して適切な権限を付与して下さい。


ほんとは、Groovy で書きたかったんですが FillSchema みたいなのが出来るのかわからなくて挫折。。
※FillSchema ってのは、データは取得せずに(クエリの結果データが存在しなくても良い)名前や型が取得出来る機能です。

*1:ちゃんと使ってないので、認識違ってるかも