最近のつぶやきから

  • WPF の勉強がてらにアプリを作成していたら、完成品を web で見つけてモチベダウン
  • WPF を投げて ASP.NET MVC2 をはじめてみた
  • http://gyazo.com/66898b0356fdc1aaa306b669a864b109.png
  • レンタルサーバで libtidy.dll が動かせなくてはまる
  • 配列どおなじように T Sum(params IEnumerable items) とか書きたいと時々みかけるが、本当に書きたいのか?配列すら書いてみたことないんちゃうんか?と問い詰めたい。と、半年ぶりに Sum(params T[]) でまたミスって思った。配列と同じならすぐ作れるだろうね。でも、T Sum(params IEnumerable items) を Sum(new List()) と呼ぶと、Sum() ではなく Sum>() に解決されるんだよ。おなじならね X(
  • なんかWin8/128bitの話題多いな。スケールあげてどうすんのはどうでもいいが、今宣伝しまくりのアイアンマン2でもみてろと。アドバンスドリアリティーデスクトップほしいね!
  • どうして標準で、
public static IEnumerable<T> ExecuteQuery<T>(this IQueryable<T> source)
{
    foreach (var item in source) yield return item;
}

って無いの?

最後のやつについて、すこしだけ補足。
IQueryable は IEnumerable を実装しているので、当然ですが IEnumerable を要求する場所や、IEnumerable に対する拡張メソッドはすべて IQueryable に対しても使えます。ただ、大きな違いとして IQueryable はシーケンス (IEnumerable 自身)に対する操作を Expression で記録しておき、シーケンスから要素を取り出そうとしたときにはじめて QueryProvider に対して Expression の解決が要求されます。

そんなわけで、LinqToSQL なんかでは、

// query is IQueryable<Tuple<int, int>>
var query = from T1 in ctx.Table1 select new Tuple<int, int>(T1.ID, T2.Number);

// enumerable is IEnumerable<int>
var enumerable = query.Where(t => t.Item1 < 10)
                      .SelectMany(t => new [] { t.Item1, t.Item2 };

foreach (var i in enumerable) { ... }

なんてことをやったら、都合よく UNPIVOT や UNION ALL を生成したりはしてくれなくて「SQL に変換できませんでした」となっちゃうのですね。そこで、

// enumerable is IEnumerable<int>
var enumerable = query.Where(t => t.Item1 < 10)
                      .ExecuteQuery()
                      .SelectMany(t => new [] { t.Item1, t.Item2 };

なんてかんじに途中に挟んで、「ここまでが LinqToSQL、ここからは LinqToObjets」という境界をつくるわけですね。