流暢な表現とクエリの表現—他のものより優れている点はありますか?


255

LINQは、ジェネリック以降の.NETの最大の改善点の1つであり、時間とコード行を大幅に節約できます。ただし、流暢な構文は、クエリ式構文よりもはるかに自然に思えます。

var title = entries.Where(e => e.Approved)
    .OrderBy(e => e.Rating).Select(e => e.Title)
    .FirstOrDefault();

var query = (from e in entries
             where e.Approved
             orderby e.Rating
             select e.Title).FirstOrDefault();

2つの間に違いはありますか、それとも他のものに対して特定の利点がありますか?


1
複雑なクエリの場合、ラムダ構文の方がわかりやすく/読みやすいと思いますが、クエリ構文は単に見栄えがしません。
nawfal

回答:


255

どちらも優れていません。異なるニーズに対応しています。クエリ構文は、複数の範囲変数を利用する場合に役立ちます。これは次の3つの状況で発生します。

  • letキーワードを使用する場合
  • 複数のジェネレーターがある場合(句から
  • 結合を行うとき

次に例を示します(LINQPadサンプルから)。

string[] fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };

var query =
  from fullName in fullNames
  from name in fullName.Split()
  orderby fullName, name
  select name + " came from " + fullName;

次に、これをメソッド構文の同じものと比較します。

var query = fullNames
  .SelectMany (fName => fName.Split().Select (name => new { name, fName } ))
  .OrderBy (x => x.fName)
  .ThenBy  (x => x.name)
  .Select  (x => x.name + " came from " + x.fName);

一方、メソッド構文は、クエリ演算子の全範囲を公開し、単純なクエリの方が簡潔です。クエリとメソッドの構文を組み合わせることで、両方の長所を利用できます。これは、LINQ to SQLクエリでよく行われます。

var query =
  from c in db.Customers
  let totalSpend = c.Purchases.Sum (p => p.Price)    // Method syntax here
  where totalSpend > 1000
  from p in c.Purchases
  select new { p.Description, totalSpend, c.Address.State };

2
素敵な答え。「.Select(name => new {name、fName})」が何をしているのか、もう少し詳しく教えてください。
キルブレーカー2010

12
それは匿名タイプでフルネームとともに個々の単語(anne、williams、johnなど)を選択します。これにより、元のフルネームを「保持」して、残りのクエリでフルネームと個々の単語の両方にアクセスできるようになります。
Joe Albahari、2010

58

この方法で式全体を記述できる場合は、後者(「クエリ内包構文」と呼ばれることもあります)を使用することを好みます。

var titlesQuery = from e in entries
                  where e.Approved
                  orderby e.Rating
                  select e.Titles;

var title = titlesQuery.FirstOrDefault();

(かっこ)を追加する必要があるとすぐに .MethodCalls()、変更します。

前者を使用する場合、通常は次のように1行に1つの句を配置します。

var title = entries
    .Where (e => e.Approved)
    .OrderBy (e => e.Rating)
    .Select (e => e.Title)
    .FirstOrDefault();

少し読みやすいと思います。


29

それぞれのスタイルには長所と短所があります。結合に関しては、クエリ構文の方が優れており、クエリ内に一時変数を簡単に作成できる便利なletキーワードがあります。

一方、Fluent構文には、クエリ構文では公開されないメソッドや操作が多数あります。また、これらは単なる拡張メソッドであるため、独自に作成できます。

クエリ構文を使用してLINQステートメントを書き始めるたびに、それを括弧で囲み、流暢なLINQ拡張メソッドを使用する必要があることに気づきました。クエリ構文には、それ自体で使用するのに十分な機能がありません。


「これらは単なる拡張メソッドなので、独自に作成できます。」-この問題に遭遇しますか? stackoverflow.com/a/3850254/1175496
The Red Pea

20

VB.NETでは、クエリ構文を優先します。

私は醜いFunctionキーワードを繰り返すのが嫌いです:

Dim fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };
Dim query =
     fullNames.SelectMany(Function(fName) fName.Split().
     Select(Function(Name) New With {Name, fName})).
     OrderBy(Function(x) x.fName).
     ThenBy(Function(x) x.Name).
     Select(Function(x) x.Name & " came from " & x.fName)

このきちんとしたクエリは、私の意見でははるかに読みやすく、保守可能です。

query = From fullName In fullNames
        From name In fullName.Split()
        Order By fullName, name
        Select name & " came from " & fullName

VB.NETのクエリ構文は、C#よりも強力で冗長ではありません。https//stackoverflow.com/a/6515130/284240

たとえば、このLINQ to DataSet(Objects)クエリ

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10

C#:

var first10Rows = (from r in dataTable1.AsEnumerable() 
                   select r)
                   .Take(10);

9
クエリスタイルを使用できないVB開発者への同情。
nawfal 2014年

1
最後のC#の例は単純すぎて価値がありません。`dataTable1.AsEnumerable()。Take(10);と書くだけです。
Emyr、2016年

@Emyr:「VB.NETのクエリ構文もC#よりも強力で冗長ではない」で始まる最後の段落は、VB.NETのクエリ構文をC#と比較するだけで、メソッド構文を使用しています。
Tim Schmelter 2016年

15

クエリ構文がまったくわかりません。私の心にはそれのための理由はありません。letは.Selectおよび匿名型で実現できます。そこにある「句読点」によって、物事はより整理されたように見えると思います。


9
流暢な構文を使用すると、複数の結合が非常に手間がかかります。私は一般的に流暢に自分自身を使用します-結合が含まれていない限り。
Roman Starkov、

1
@Instance Hunter:こちらも同じです。流暢な構文の考え方を理解するのにかなり時間がかかりました。強力な列挙可能関数および「純粋な」関数のアイデアと組み合わせて、今では本当に楽しんでいます。以前はトリッキーな状況で、適切なコード表現がありませんでした。脳のye-ole-SQL-partについては、クエリ構文があることはまだ幸運です。
Xan-Kun Clark-Davis

13

場所があるだけなら、流暢なインターフェース。selectまたはorderbyが必要な場合は、通常、Query構文を使用します。


8

流暢な構文は確かにより強力に見えますが、コードを小さな再利用可能なメソッドに編成するためにもうまく機能するはずです。


5

私はこの質問にC#のタグが付けられていることを知っていますが、VB.NETではFluent構文は非常に冗長です。


4

私はFluent構文が本当に好きで、可能な場合はそれを使用しようとしますが、結合を使用する場合など、特定のケースでは、通常はQuery構文を使用します。ラムダよりクエリ(SQLのような)構文に慣れています。


4

私は理解し、流暢な形式が好きですが、読みやすさの理由から、当面はクエリにこだわっています。LINQを紹介されたばかりの人にとっては、Queryの方がずっと読みやすいでしょう。


4

SQLを使用する従来のWebプログラミングから来たので、クエリ構文を好みます。私の頭を包む方がはるかに簡単です。しかし、.Where(lambda)は間違いなくはるかに短いので、利用し始めると思います。


4

私はLinqを約6か月間使用しています。T-SQLと非常によく似ているので、私が最初にそれを使い始めたとき、クエリ構文を好みました。

しかし、拡張メソッドとして再利用可能なコードのチャンクを記述し、それらをチェーンするだけで簡単にできるようになったため、今は徐々に前者に取り掛かっています。私は各節を1行に置くとわかりやすくなりますが、


3

私は私たちの会社の基準を設定したばかりで、拡張メソッドの使用を強制します。どちらか一方を選択し、コードで混同しないことをお勧めします。拡張メソッドは、他のコードのように読み取ります。

内包構文には、すべての演算子がなく、クエリを括弧で囲んで、拡張メソッドを追加します。最初から拡張メソッドを使用するように頼むだけです。

しかし、ほとんどの場合、いくつかの例外はありますが、個人的な好みです。


3
私は個人的な好みを強制しません。しかし、それは私です。
Memet Olsen 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.