2016-09-09 29 views
0

いくつかのフィルタを使用してIQueryableクエリ式を構築しています。ある時点で、式に行があり、結果に依存して別のクエリを実行するかどうかを確認したい。下の例では、Anyがデータベースにヒットするため、データベースに3ヒットしました。データベースにアクセスせずにIQueryableでFirst()メソッドを使用する

時間の前にデータベースにアクセスすることなくAnyの機能を再利用する方法はありますか(すべての利点があるWhere()など)。この場合

IQueryable<Car> visibleCars = context.Cars.Where(c => c.Status == "V"); 
IQueryable<Car> invisibleCars = context.Cars.Where(c => c.Status == "I"); 
IQueryable<Car> c = visibleCars.Any() && invisibleCars.Any() 
        ? context.Cars.Where(c => c.Status == "x").ToList(); 
+0

どのようにそのコードはコンパイルさえありませんか?どのように 'Any()'は 'Where()'のように動作しますか?必要に応じて述語を 'Any()'に渡すことができます。それはあなたが意味することですか? DB上の実際のクエリを避けるとは思えません。 DBデータをキャッシュする必要がありますが、実用的でない場合もあります。ここで成し遂げることができるとは思っていませんし、実際にそれを理解するためにシナリオについて十分な詳細を提供しているわけでもありません。 –

+1

'WHERE'はクエリを構築する"ちょうど "です - 究極のWHERE句の部分です。しかし 'Any()'や 'First'を使うと、(与えられたラムダ式の)行があるかどうかを知りたければ**データベースへのアクセスが必要です** - 行が存在するかどうかをチェックする方法はありません。実際にデータベースに行くことはありません。これらの2つは**基本的には**異なる操作です。** **はありません。データベースに対するクエリなしで存在または行をチェックすることはできません。 –

+0

このコードは確かにコンパイルされません。あなたが試みるかもしれない何かは.Top()です。これはIQueryableを返すので即座に実行されません。ただし、コンパイラが式を評価する必要がある場合は、常にdbヒットとなります。 – DevilSuichiro

答えて

0

、あなたは他のクエリあなたwhere句の一部を行うことで何の結果を生成しないクエリを得ることができる必要があります。より一般的なアプローチとして

IQueryable<Car> c = context.Cars 
    .Where(c => c.Status == "x" 
     && visibleCars.Any() 
     && invisibleCars.Any()) 
    .ToList(); 

、あなたは多くの場合、1回のラウンドトリップで複数のチェックを実行するためにGROUPBYでトリックを使用することができます。

var interestingData = context.Cars 
    .GroupBy(c => false)   // always get one result 
    .Select(g => new 
    { 
     AnyVisibleCars = visibleCars.Any(), 
     AnyInvisibleCars = invisibleCars.Any(), 
     CarsWithXStatus = visibleCars.Any() && invisibleCars.Any() 
      ? g.Where(c => c.Status == "x") 
      : g.Where(c => false) 
    }) 
    .Single(); 
+0

これは本当に機能しますか?生成されたSQLがどのように見えるか考えていますか?私はNHibernateを使用していますが、これは通常このような複雑なクエリでは失敗しますので、EFがこれを処理できればうまくいくでしょう。 – Groo

+0

@Groo:最初のアプローチのSQLは非常に面倒ですが、うまくいくはずです。私は、データベースがクエリを非常にうまく最適化するほどスマートであるかどうかはわかりません。私の2番目のアプローチのような何かがより良いパフォーマンスを発揮するかもしれません。 – StriplingWarrior

+0

生成されたクエリが気になる場合は、LinqPadを実際のコードと同じドライバで使用してください... – Phil1970

関連する問題