こんにちは。自動化の深淵を覗き込み、システムを自在に操るエンジニアの皆さん。
今日は、VBAの「マクロの記録」という心地よいゆりかごを卒業し、VB.NETという強力な武器で「動的クエリ構築」という領域に足を踏み入れる皆さんのために、少し刺激的な話をしましょう。
初心者がやりがちな「文字列でSQLを組み立てる」という危険な道は捨ててください。これから学ぶのは、`Expression(Of TDelegate)`を用いた、型安全かつ堅牢な「式ツリー(Expression Tree)」による動的クエリの構築です。
—
1. なぜ「文字列結合」が罪深いのか?
検索条件を作る際、初心者はよくこうします。
`”SELECT FROM Users WHERE Name = ‘” & userInput & “‘”`
これは、SQLインジェクションのリスクがあるだけでなく、コンパイル時に何のチェックも受けない「ただの文字列」です。バグの温床であり、保守性の欠片もありません。
プロフェッショナルは、「プログラムをデータとして扱う」という手法をとります。それが「式ツリー」です。
—
2. Expression(Of TDelegate) の正体
式ツリーとは、コードを「実行する」のではなく「構造として記述する」仕組みです。
`Expression(Of TDelegate)` を使うと、コンパイラはコードを木構造(ツリー)として保持します。これにより、実行時に「WHERE句の条件をあとから付け足す」といった魔法のようなことが可能になります。
図解:式ツリーの構造
- Root (λ式): `p => p.Age > 20`
- Left (パラメータ): `p` (Userオブジェクト)
- Body (比較演算): `Greater Than`
- Right (定数): `20`
この構造をプログラム上で組み立てるのが、今回のゴールです。
—
3. 実践:動的クエリ構築のコード例
ユーザーが「名前」や「年齢」を自由に入力して検索できるシステムを想定しましょう。
Imports System.Linq.Expressions
Public Class UserSearcher
‘ 検索条件を動的に構築するメソッド
Public Function CreateFilter(name As String, minAge As Integer) As Expression(Of Func(Of User, Boolean))
‘ p => … の「p」の部分を作る
Dim parameter = Expression.Parameter(GetType(User), “p”)
‘ 最終的な条件式を保持する変数
Dim body As Expression = Nothing
‘ 名前が指定されていれば条件を追加
If Not String.IsNullOrEmpty(name) Then
Dim nameProp = Expression.Property(parameter, “Name”)
Dim nameVal = Expression.Constant(name)
‘ p.Name == name
Dim nameExp = Expression.Equal(nameProp, nameVal)
body = nameExp
End If
‘ 年齢が指定されていれば条件を追加
If minAge > 0 Then
Dim ageProp = Expression.Property(parameter, “Age”)
Dim ageVal = Expression.Constant(minAge)
‘ p.Age >= minAge
Dim ageExp = Expression.GreaterThanOrEqual(ageProp, ageVal)
‘ すでに条件があれば AND で結合、なければ新しく作る
If body Is Nothing Then
body = ageExp
Else
body = Expression.AndAlso(body, ageExp)
End If
End If
‘ ツリーをラムダ式に変換して返す
Return Expression.Lambda(Of Func(Of User, Boolean))(body, parameter)
End Function
End Class
—
4. プロの視点:陥りやすい罠
この技術を扱う際、初心者が必ずと言っていいほどハマるポイントが2つあります。
1. 型不一致エラー: `Expression.Constant` に渡す値の型と、プロパティの型が完全一致していないと、実行時に例外が発生します。`Integer` と `Long` の違いすら許されません。厳密に型を合わせてください。
2. Nullの考慮: `body` が `Nothing` のままラムダ式を生成しようとするとクラッシュします。上記のコードのように、初期化と結合のロジックを慎重に組む必要があります。
—
5. まとめ:ここをクリアすれば「中級者」の入り口です
式ツリーを使いこなせるようになると、単なる「コード書き」から、「システムの挙動を設計するエンジニア」へと進化します。
- 型安全: コンパイル時に型チェックが効く。
- 柔軟性: ユーザーの入力に合わせてクエリを無限に拡張できる。
- パフォーマンス: Entity Framework等のORMと組み合わせれば、SQLに変換される際の最適化まで享受できる。
VB.NETは古い言語だと言われることもありますが、その裏側にある .NET Framework の本質を理解すれば、これほど強力なツールはありません。「マクロの記録」の先にある、この論理的で美しい世界をぜひ楽しんでください。
何か詰まったら、いつでも戻ってきてください。皆さんのコードが、より堅牢で美しいものになることを応援しています!
