2009-11-04 11 views
7

私は.Where(x => x.a == 1).Where(x => x.b ==1)に後者のターンを理解するとして、私はwhere x.a==1 && x.b==1 LINQ-to-SQLのwhere句と&&演算子の違いは何ですか?

として
where x.a==1 
where x.b==1 

を書くことができますが、どのようにこれはDBに変換ないように見えますか?最適化の点でどちらが良いでしょうか?私はいつもプロファイラから実行されたクエリを見ることができますが、それは一般化されることはほとんどありませんが、私が頼りにしたくない単一の経験的観察に似ています。

リフレクター付きのSystem.Linq名前空間は別のオプションですが、多くの人が同じ時間を費やすことを避けるチャンスがありません。答えが得られないなら、私はそれをします。

+2

ほとんどの複製http://stackoverflow.com/questions/1648730/when-using-linq-what-is-the-difference-between-and-multiple-where-clauses –

+0

私は私の中でそれを見つけられませんでしたとにかくこれはLINQ-to-SQL固有のものです。 –

+0

LINQ-to-Objectsへの影響は明らかですが、LINQ-to-SQLは不明です。 –

答えて

7

ここでは、しばらくの間、Reflectorの出力を行った後の私の発見です。 LINQツーオブジェクトはほとんど& &オペレータのように動作し、それを引き起こしてWhereArrayIteratorWhereListIteratorを使用した場合の連続where述語を組み合わせることではなく、まったく同じように:

節はこのように見てFunc<TSource, bool>に変換どこx.a==1 && x.b==1使用する場合:

bool daspredicate(TSource x) 
{ 
    return x.a==1 && x.b==1 
} 

ただし、連続するWhere句を使用すると、少なくともJITされていないIL-アスペクトからわずかなパフォーマンス上のペナルティがあります。

bool predicate1(TSource x) 
{ 
    return x.a==1; 
} 
bool predicate2(TSource x) 
{ 
    return x.b==1; 
} 
bool daspredicate(TSource x) 
{ 
    return predicate1(x) && predicate2(x); 
} 

これは、追加の関数呼び出しのオーバーヘッドが含まれていることがわかります。 JITが関数をインライン化しない限り、これはかなり高価になります。私はそれがうまくやっていると確信していますが、JITの仕事は、必要な場合を除いて、自分たちのWhereステートメントを組み合わせるとずっと簡単になります。

しかしSQL側では、クエリは同じです。実行前でも、デバッガはクエリオブジェクトを同じSQL文に評価します。物事ははるかに複雑に思えたので、私はLinq名前空間であまりにも遠くに行くことはできませんでしたが、クエリは同じなので、上記のLINQからオブジェクトへの例とは違って、ペナルティはありません。

EDIT:SQLサーバー上でネストされたサブクエリをもたらす複数のwhereステートメントを見たことがあります。私は、あなたが安全な側にいることができるときはいつでも、どこに声を掛けて声を出すのが良いかと思います。

2

ここで正しいことをするのはLINQ to SQLです。 2つの「where」節を1つのSQL句に変換し、2つの部分を「AND」で結合すると思います。

両方をお試しください。ただし、生成されたSQLに違いがあることは間違いありません。

IMOあなたは常に非自明な何のために生成されたSQLを確認する必要がありますが、LINQは確かを動作する方法は、小さな節からそれを構成することにより、大規模なクエリを構築するあなたを奨励 - ので、私は本当に期待したいですそれはちょうど働くこと。

+0

それはそれのように見える、ありがとう! –

2

DB側が同じです。これは、Linq-to-SQLを構成可能な副作用に過ぎません(つまり、1つのクエリで開始し、それに基準を追加したり、予測を変更するなど)。

2

コード:

where x.a==1 
where x.b==1 

または

where x.a==1 && x.b==1 

はとにかくC#のためのシンタックスシュガーです。それはあなたがそれはおそらくだろう推測と同じように

Where(...).Where(...) 

のLINQメソッドチェーンとしてコンパイルされますので、私は本当に、生成されたSQLの違いがある疑い。 JetbrainsのResharperのようなツールを試してみてください。テスト用に書き直す時間を節約するために、2つの間で自動的に変換する選択肢を提供するintellisenseも提供しています。

本当に単純なクエリをメソッドチェーンとして記述することができます(たとえば、コレクション/テーブルが1つしかなく、結合がない場合など)。また、より表現豊かなLinqの砂糖構文ではより複雑なものもあります。

+0

どうやら彼らはあまり同じではない、私の答えを参照してください。 –

関連する問題