Daigo Hamura's Weblog

DLINQ は Magic か?

LINQ Project では In-Memory Query と DLINQ Query に同じ Query Expression が使えます。 コンパイラは Query Expression が In-Memory に対してかそれとも Relational DB なのか分かるのか?と言う質問をよくされます。  コンパイラがすごい事をしていると誤解されているようですので、その説明をちょっとだけ。 

特に Magic は無く、Trick としては C# 3.0 で新しく追加された
   1. Query Operators はオーバーロード可能
   2.  lambda 式は Expression<Func<...>> にアサインされた場合 Expression Tree を IL の代わりに Emit する

の二つだけです。例えば、LINQ In-Memory Query の場合
      var q = from x in new int[]{1,2,3,4}
             where x > 2
             select x;

            int[] q = (new int[]{1,2,3,4}).Where(x => x > 2);
に、まず変換されます。ここで使われる Where Operator は
   IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)
です。 理由は 普通に Overload  の解決で IEnumerable<T> へ Implicitly Convertable な new int[] が最初の Where Operator の引数だからからです。

では、DLINQ Query の場合を見てみると、
          var q = from x in db.Customer
             where x.ContactName == "Hoge"
             select x;

         q = db.Customer.Where(x => x.ContactName == "Hoge");
にと書き換えられ、          
         Query<T> Where<T>(this Query<T> source, Expression<Func<T, bool>> predicate)
の Where Operator が使われます。Trick 1で書いたQuery Operator は Overload 可能がキーポイントです。 最初のdb.Customer プロパティ の戻り値の型は Table<T>。 クラスの関係は
   IEnumerable<T>
      |
   Query
<T>
      |
   Table
<T>
よって、Overload の解決は Table<T> により近い Query<T> へと、つまり、Where<T>(this Query<T>..) の方が Where<T>(this IEnumerable<T> ...) よりも Better となる訳です。 ここで先ほどの Trick の2番目、lambda 式の Expression<Func<..>>への変換が登場します。 Query Expression の中の
      x => x.ContactName == "Hoge"

   Query<T> Where<T>(this Query<T> source, Expression<Func<T, bool>> predicate)
の Where Operator が使われる事により、2番目の引数、Expression<Func<T, bool>> へとアサインされます。 lambda 式は Expression<Func<...>> にアサインされた事により無事にExpression Tree に書き出される事になります。

Dlinq Engine は Expression Tree を元に C# から SQL の変換を行い Database へ SQL Query をなげ、結果を得ます。

このように、LINQ は既存の言語の仕様の上に成り立っていると言うのが分かっていただけたかと思います。

Published Sunday, April 16, 2006 7:59 PM by daigoh
Filed under:

Comments

 

福井 厚のBlog (Atsushi Fukui's blog) said:

波村さんのblogより
Daigo Hamura's Weblog : DLINQ は Magic か?http://blogs.msdn.com/daigoh/archive/2006/04/16/577320.aspx...
April 17, 2006 1:47 AM
 

青柳臣一 blog : .NET や C# がメインの blog said:

DLINQ は魔法でできています
April 18, 2006 5:45 AM
Anonymous comments are disabled

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker