14

LINQ to SQL を使用して、Sql サーバー 2008 で FullTextSearch ストアド プロシージャの検索結果を取得しています。プロシージャをサーバー エクスプローラーからデザイナーにドラッグし、適切な戻り値の型とパラメーターを使用してメソッドを作成しました。問題は、このメソッドを呼び出した結果のカウントを取得する必要があるため、リポジトリ メソッド (Sproc メソッドを呼び出して結果を IQueryable として返す) を使用して、次の呼び出しを行うことです。

var result = repository.FullTextSearch(searchText);
        int resultsCount = result.Count();
        var ret = result.Skip((pageNumber - 1) * PageSize).Take(PageSize).ToList();

このコードは、実行しようとするたびに InvalidOperationException を生成します。例外には、「クエリ結果を複数回列挙することはできません」というメッセージが表示されます。

Sproc 用に生成されたメソッドは ISingleResult を返しますが、これは私の知る限り OK です。ビューでページングをサポートする必要があるため、ページの総数を知る必要があります。これは、すべてのアイテムの数を取得できる場合にのみ可能です。

ここで何が欠けていますか?

4

4 に答える 4

17

できることは、 のToList()後に呼び出しを追加することですrepository.FullTextSearch(searchText)。このようにして、結果はサーバーから取得され、その後、必要に応じて処理を実行できます (メモリ内にロードされるため)。

あなたが今やろうとしているのは、同じ SQL クエリを 2 回実行することですが、これはかなり非効率的です。

于 2009-09-01T08:43:06.993 に答える
14

これはストアドプロシージャを実行しているため、すべての素敵なSkip/Takeはとにかく冗長です...すべてのデータを戻すしかありません(ストアドプロシージャの呼び出しは構成できません)。それができる唯一のことは、それらのいくつかのオブジェクトを具体化しないことです。

より良いアプローチは、コードをリファクタリングして 2 つの呼び出しを行うことではないかと思います。

int result = repository.FullTextSearchCount(searchText);
var result = repository.FullTextSearch(searchText, skip, take); // or similar

つまり、ページング パラメータを SPROC の一部にします (およびROW_NUMBER()/ OVER(...)、またはテーブル変数、一時テーブルなどを使用して、データベースでのフィルタリングに) - あるいはOUTPUT、sproc のパラメータと同様のものを作成します。

int? count = null;
var result = repository.FullTextSearch(searchText, skip, take, ref count);

( TSQLは実際には入力+出力であるため、 にOUTPUTなることを思い出したようです)refOUTPUT

于 2009-09-01T08:45:45.597 に答える
5

を使用ToList()すると、この問題を回避できます。

var result = repository.FullTextSearch(searchText).ToList();
于 2011-11-03T09:13:16.583 に答える
1

カウントが必要な場合は、最初に結果を実行することをお勧めします。結果の実行で resultsCount を使用しないため、リスト自体からカウントを実行します。

var result = repository.FullTextSearch(searchText);
var ret = result.Skip((pageNumber - 1) * PageSize).Take(PageSize).ToList();
int resultsCount = ret.Count();
于 2009-09-01T08:53:49.920 に答える