2

私は次のようなことをするかどうか疑問に思っていました:

var results = source.Where(c => c.Name == "Whatever");

Count() または ToList() を呼び出す前に、クエリが何かを返したかどうかを確認する方法はありますか? Where() が遅延して実行されることはわかっています。

返されるデータ セットは巨大になる可能性があり、上記のメソッドの呼び出しにはかなりの時間がかかります。

resultsも NULL になることはありません...

ありがとうございました。

4

5 に答える 5

6

完全な結果セットを取得する価値があるかどうかを知りたいだけなので、これを行う価値はありません。

ここには 2 つの状況しかありません。

  1. クエリの結果はありません。この場合、結果がいくつあるかを確認するクエリは、実際のクエリとまったく同じくらい実行に時間がかかり、正確に同じ量の情報を返します。この場合、何も得られません (ただし、何も失うこともありません)。

  2. クエリには少なくとも 1 つの結果があります。この場合、戻って実際のクエリを実行する必要があります。正味の結果として、最初にチェックしない場合と同じくらい多くの時間を費やすことになりますが、結果があるかどうかをチェックするための追加コストも発生します。このチェックは、データベースへのラウンドトリップを意味しますが、これはかなりの時間です。

クエリにアイテムが含まれるかどうかを知りたい場合は、それが可能です。(Any拡張メソッドを使用するだけです。)ただし、結果が何であるかに関係なく、実際の項目が何であるかを知る必要がない場合にのみ有益Anyです。

lazyberezovsky が彼の回答で行ったように、 を呼び出した後にクエリの結果が変化する競合状態も考慮する必要があることも注目に値しますAny

于 2013-01-24T20:11:47.337 に答える
3

クエリが何かを返すかどうかを知る唯一の方法は、そのクエリを実行することです。したがって、結果を取得したり、結果の数/存在を確認したりできます。ただし、2番目のケースでは、クエリをさらに実行しても同じ結果が得られるかどうかを確認できません。

サンプル:

List<int> items = new List<int>() { 1, 2, 3 };
var query = items.Where(i => i > 0);
// query is not executed at this point
var count = query.Count(); // first execution, returns 3
items.Clear();
var positiveItmes = query.ToList(); // ooop, no items here!

したがって、クエリ間でデータが変更されないことが確実な場合(あなたは完全ですか?)、すべてのデータを取得する前に使用Count()できます。Any()それ以外の場合は、のようなデータをロードする必要がありますToList()

于 2013-01-24T20:00:37.730 に答える
1

確かに Any を使用するだけで、結果があるかどうかがわかります。

results.Any();

MSDN によると:

このメソッドは、コレクションの要素を 1 つも返しません。代わりに、コレクションに要素が含まれているかどうかを判断します。ソースの列挙は、結果が決定されるとすぐに停止されます。

MSDN 任意

于 2013-01-24T19:54:57.323 に答える
0

有用な提案と精度をありがとう。私はこれを私の汎用EFリポジトリに実装することになりました:

    public bool CheckExists(string tableName, string whereField, string whereValue)
    {
        string query = string.Format("SELECT COUNT(*) FROM {0} WHERE {1} = {2}", tableName, whereField, whereValue);
        var count = _context.ExecuteStoreQuery<int>(query).FirstOrDefault();
        if (count == 0)
            return false;
        else
            return true;
    }

はるかに高速!:)まだクエリを実行していますが、LINQ / EFに潜在的な結果を複雑なクラスタイプのIENumerableに変換するように依頼していないので、問題ないようです。

于 2013-01-24T20:27:05.177 に答える
-2
var any = (source.Where(c => c.Name == "Whatever").FirstOrDefault() != null);

FirstOrDefaultはSELECTTOP1(LinqToSql)として実行されます

于 2013-01-24T20:01:14.683 に答える