rider.お品書きサクッと書いて公開して、後でちまちま修正する事がママあります。なんじゃこりゃ?と思ったら、数日してから見て貰えると嬉しいです。「スクラムの実践方法を分かりやすくマンガも交えて解説。表形式と構造化形式SQL文に変換可能かどうかを、もう少し見てみる。Debug.WriteLine(customer.ToString());}このLINQクエリはもちろん成功し、以下のように変換される。[Extent2].[AddressType]完璧に意図通りだ。CLR固有のものだが、SELECT句でカラムに別名を適用して全て吸い上げている。SQL文には表れないが、結果が返された時点で匿名クラスのそれぞれのプロパティに格納されるのだろう。LINQクエリのjoinは、内部結合に該当する。対応する予約語は存在しない。Objectsでのjoinにも、そのような演算が無いことを意味する。そもそも左・右結合は、RDBが「表形式」でしか結果を表現できないために存在するものだと分かれば、大した問題ではない。これらの結合は、対応する値が存在しない場合でも、結果表中の該当するカラムに何らかの値を置く必要があり(そうしないと「表」にならない)、仕方がないので「NULL」を返すのだ。LINQの世界は表形式だけではなく、(XMLのように)構造化された要素を自在に扱う事が出来る。そこに結果が存在しな場合はNULLで表現しなくても、はじめから存在しない状態を作り出せる。BY句を彷彿とさせる。BY句と同じように動作する。U>インターフェイスの列挙子が返される。U>が構造化されたような形をしている。一つのキー値(T)に対して、n個の要素値(IEnumerable<U>)が格納される。IDictionaryが「表形式」と考えるなら、IGrouping(IGroupingの列挙子)は「構造化形式」だ。得られるSQL文は分かりにくい。ASCサブクエリバリバリな、読みにくいSQL文が出力された。ProductCategoryIDをDISTINCTしたリストを作る(一番内側のクエリ)つまり、カテゴリーIDの重複のないリストを作る。JOINのクエリ)ここでC1とC2という付加情報を加えている。C1は1固定なので用途が分からないが、C2はカテゴリーに該当するレコードが存在したかどうかを表しているように見える。最後に、結合結果をカテゴリーIDとC2でソートする。このようなSQL文となる理由はあまり思いつかず、はっきりとした理由は不明だ。最終的にカテゴリーID毎に集約しなければならないため、カテゴリーIDでソートするのは理に適っているように思える(逆シリアル化してインスタンスに格納するときに、ソートされていれば順序実行すれば良くなる。件数が莫大かもしれないため、返却後にインメモリでソートしない方が良いだろう)。Entitiesのバージョンが上がる時に変更される可能性があるので深入りしないが、重要なのは、RDBとのやりとりはどうしても「表形式」とするしかないが、結果が戻ってきたら、「構造化形式」に集約出来ると言う事だ。構造化されていれば、結合結果としてカラムチェックに頼らなければならないような、書きにくいコードから解放される。}}もちろん、LINQクエリなので、パイプライン実行される。BYが実行されるので一時リソースを消費するが、.NET側では結果のレコード群が逐次処理される。最終出力はConsoleに出しているだけなので、結果が何千万行あってもメモリは圧迫されない。今まで苦労してきた開発手法は一体何だったのか、と思わずにはいられないかもしれない。集約の簡便さもさることながら、コードを一瞥しただけで処理内容が把握できるため、保守も容易だ。このコードにはforeach以外に制御構文が存在しない。サイクロマティック複雑度は十分に小さい。それはつまり、テストに掛かるコストも小さいと言う事だ。最後に、結果をXMLに変換するのに、制御構造が不要である例を示そう。XMLの間にゲートを作っていることに注意。Entitiesの一部とみなされ、SQL文に変換しようとして失敗する。従来の制御構文によるロジックバリバリのコードのユニットテストと異なり、このコードのテストは純粋なインターフェイス境界のテストとして非常に設計しやすいはずだ。この事を知っていれば、機能設計の段階から設計方針が異なってくる。(但し、ユニットテストとして成立させるためには、DataContextを分離する必要がある事に注意。このままではデータベースが存在しないとテスト出来ないので良くない)。WordPress%d人のブロガーが「いいね」をつけました。