2009-03-10 5 views
54

私は一般的にLINQを使用し始めています(これまでのところ、XMLとtoSQL)。私は時々同じ結果を達成するための2つ以上の方法があることを見てきました。私の知る限り理解し、両方がまったく同じことを返す、この単純な例を見てみましょう:私は、構文または欠落しているパラメータまたは違いに作られた可能性のあるすべてのミス以外にもLINQ:ドット表記とクエリ式

SomeDataContext dc = new SomeDataContext(); 

var queue = from q in dc.SomeTable 
     where q.SomeDate <= DateTime.Now && q.Locked != true 
     orderby (q.Priority, q.TimeCreated) 
     select q; 

var queue2 = dc.SomeTable 
     .Where(q => q.SomeDate <= DateTime.Now && q.Locked != true) 
     .OrderBy(q => q.Priority) 
     .ThenBy(q => q.TimeCreated); 

を、アイデアは、2つの方法にはあるということです同じことを表現する。私は、最初の方法にはいくつかの制限があり、 "ドット表記法"がより完全であることを理解していますが、それ以外にも利点はありますか?

+0

皆様にお返事ありがとうございます。うーん、私は正しい答えとして1つだけマークすることができます。しかし、私はすべてのコメントを感謝します。 –

+1

重複:http://stackoverflow.com/questions/214500/which-linq-syntax-do-you-prefer-fluent-fluent-or-query-expression – Mikhail

答えて

48

「ドット」表記は、通常ラムダ構文と呼ばれます。最初の表記法はいくつかの名前が付いていますが、私は通常これをクエリ構文と呼びます。

私は10人の開発者のチームで作業しており、私たちは標準として使用するべき長さについて議論します。一般的に、(LINQの)より多くのシーズン開発者はラムダ構文に移行しますが、大きな例外があります。

ラムダはより簡潔ですが、複数のテーブル結合を実行するのは悪夢です。ジョインはクエリの構文でははるかにクリーンです。反面、ラムダ構文内に存在する多くのLINQ操作があります:Single()、First()、Count()など

したがって、あなたが最も快適に感じるものを使用してください。あなたが経験を得ると、あなたの好みはおそらく変わるでしょう。両方を読むことができることには大きな価値があり、両方の少しを使用しなければならない状況が確実に存在します。他の状況では、他のものよりも1つのスタイルにそれを貸すでしょう。結局、すべてが同じ実行可能コードに変換されます。

+1

5年後、メソッド連鎖ラムダ構文は現在、一般的に[Fluent Interface](http://en.wikipedia.org/wiki/Fluent_interface)と呼ばれています。 – Nick

8

まあ、 'ドット'表記ははるかに短くすることができます。テイク:

var result = from p in dc.Products 
      where p.Id > 5 
      select p; 

か:

var result = dc.Products.Where(p => p.Id > 5); 

それははるかに短く、そしてより読みやすいので、私は後者を好みます。

+0

LINQ to SQLを使用すると、前者はT- SQL(これはDBクエリを書くときに便利です)と、後者は他のLINQクエリ(LINQ to XMLなど)のために使います。 – RobS

+0

はい、そこにポイントがあります。 linq2sqlでは、私はしばしばあなたが言及したのと同じ理由で、最初のバージョンを使用します。上記のような非常に単純なクエリの場合は、私が怠けているために、2番目の短いバージョンを使用することがよくあります.-) – Razzie

+0

いつも短くはないし、読みにくいこともありますが、それは少し短くすることができます。 –

2

これらは同じコードでコンパイルされるか、最初に最初のコードが最初のコードに変換されてからコンパイルされます。

違いは、最初のバージョンがよりクリーンだが制限があるということです。 2番目の例では、たとえば、既存のデリゲートを使用できます。例:

Func<int, bool> isEven = i => i%2 == 0; 
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine); 
+0

完全に真実ではありません。既存のデリゲートを使用することもできます。たとえば、 var result = from s from isEven.Invoke(s.Length) select s; – Razzie

+0

はい、しかし、スタイルについて話しています* .Invokeは単に醜いです:) – user76035

+1

あなたはInvokeを使用する必要はありませんが、これはうまくいきます: var result = from i ints where isEven(i)select i; – theburningmonk

27

大文字と小文字を区別して、私のクエリでより読みやすい構文を使用します。

可能であれば(それは、クエリの最後にFirst()への単一の呼び出しの場合など)は時々それは大丈夫ですが、私は、両者を混合し、一致しないようにしてください。

他の人が言ったように、クエリ式がちょうどに翻訳され
var query = from x in y 
      orderby z 
      group x by x.Name into groups 
      // etc 
      select foo; 

var page = query.Skip(50).Take(10); 

」:繰延実行は、その変数にはクエリ式を使用して変数に結果を代入して、を使用してドット表記を使用するために、同じように効率的だ意味します通常の "C#3を使用しているため、これにペナルティはありません。

+3

+1をもう一度括弧で囲むのではなく、一緒に使いたい場合は、もう一度分割してください。 – Shibumi

3

ラムダの表記法は、より洗練されており、より簡潔です。私はちょうどラムダ式がメソッド呼び出しの中にある場合、デバッグモードでオンザフライでコードを変更することはできません...

+0

クエリ式を使用している場合は編集して続行しますか? –

+0

@MichaelFreidgeim - No. :-)この答えをペニングしてから2年後に発見したことの1つ。 –