rider.お品書きサクッと書いて公開して、後でちまちま修正する事がママあります。なんじゃこりゃ?と思ったら、数日してから見て貰えると嬉しいです。「スクラムの実践方法を分かりやすくマンガも交えて解説。ExpressionとLINQ前回、ラムダ式をExpressionクラスとして扱う例を示した。これの何がLINQと関係あるのかと思うかもしれない。0);どちらも同じ結果が得られる(乱数であることを除けば)。0」は、メソッド構文のWhere拡張メソッドと対比する事が分かる。メソッド構文ではラムダ式で記述しなければならない。単なる式だけでは、結果はbool値になってしまうからだ。predict);}となっていて、第二引数(拡張メソッド呼び出しでは、第一引数相当)はデリゲートを渡さなければならない。このデリゲートによって、列挙子enumerableの一つ一つの要素が(呼び出し側のラムダ式によって)評価されて抽出が実現する。式を評価するので、bool値を渡しても意味がないわけだ。ここで唐突だが、QueryableクラスのWhereメソッドを見てみよう。predictExpression);}Queryableクラスは、IQueryableインターフェイスに対するLINQ拡張メソッド群を定義している。Objects)として使うこともできる。Objectsを使うときには、このインターフェイスを使わない。EntitiesのDbContextクラスだ。正確には、これらのクラス(ウィザードで生成した継承クラス)に定義されている、テーブルを模したプロパティ(AdventureWorksDataEntities.Customerなど)が、IQueryableインターフェイスを実装した型なのだ。Debug.WriteLine(customers.ToString());}CustomerプロパティはDbSet<Customer>クラスだが、このクラスはIQueryable<Customer>を実装している。そのため、以降のクエリは全てQueryableクラスの拡張メソッド群が使用され、最終的な式もIQueryable<Customer>となる。一度、Queryable.Where()の第二引数を見ると、「Expression<Func<T>>」となっている。“Johnson”」は、デリゲートとして渡されるのではなく、Expressionとして渡されるのだ。まとめると、DataContextやDbContextを使用すると、Enumerableクラスの実装ではなく、Queryableクラスの拡張メソッドが呼び出され、ラムダ式で記述した絞り込み条件(他、orderbyやselectの式も同様)は、デリゲートではなくExpressionクラスで渡されることになる。してそうなっているのか?もう見えてきたかもしれない。Expressionで渡されれば、記述した式そのものの構造を解析する事が可能となる。前回、プロパティを参照するラムダ式をExpressionで取得して、ここからプロパティ名を取得する方法を紹介した。同様に、Whereに渡された絞り込み条件のラムダ式から、絞り込み条件として記述した式の構造そのものにアクセスする事が可能となる。式で使用したプロパティ名はもちろん、比較式(上記の例では==による文字列との比較や、比較対象の”Johnson”という文字列)も抽出する事が可能だ。複雑な、括弧がネストしたり、複数のプロパティを参照したり、メソッドを呼び出したり、これらを複雑に組み合わせた式も、Expressionから解析する事が出来る。Serverに送信して実行させているのだ。Objectsのように、クエリ結果が大量にインメモリで処理されるという心配は無用だし、基本的にLINQクエリで記述したクエリの効率は、生のSQL文字列で(SqlConnectionやSqlCommandを使って)実行したものと変わらない事になる。LINQクエリは文字列に頼らないのでタイプセーフだ。前回示したように、リファクタリングツールでも意味が解析されて正しい箇所だけが更新される。Serverのテーブルから生成していれば、エンティティクラスの型定義も間違えようがない。SqlDataReaderでちまちまと型変換しながらレコードを処理する邪魔なコードを書かなくていい。いった、本来人間がやるべきではない作業を自動化する事が出来るようになる。WordPress%d人のブロガーが「いいね」をつけました。