12

ユーザーが要求した行を返すページング API がありますが、コレクション全体ではなく、一度に非常に多くの行しか返しません。API は設計どおりに機能しますが、(適切なページ計算のために) 利用可能なレコードの総数を計算する必要があります。API 内では、Linq2Sql を使用し、最終的にリクエストを行う前に IQueryable で多くの作業を行います。カウントを取得するときは、次のように呼び出します: totalRecordCount = queryable.Count();

結果として得られる SQL は興味深いものですが、不要な Order By が追加され、クエリが非常に高価になります。

exec sp_executesql N'SELECT COUNT(*) AS [value]
FROM (
    SELECT TOP (1) NULL AS [EMPTY]
    FROM [dbo].[JournalEventsView] AS [t0]
    WHERE [t0].[DataOwnerID] = @p0
    ORDER BY [t0].[DataTimeStamp] DESC
    ) AS [t1]',N'@p0 int',@p0=1

IQueryable を使用しているため、SQL サーバーに送信する前に IQueryable を操作できます。

私の質問は、OrderBy を含む IQueryable が既にある場合、Count() を呼び出す前にその OrderBy を削除することは可能ですか?

のように: totalRecordCount = クエリ可能。NoOrder .Count();

そうでなければ、大したことはありません。OrderBy の方法について多くの質問がありますが、Linq 式から OrderBy を削除することに関する質問はありません。

ありがとう!

4

6 に答える 6

3

OrderBy残念ながら、演算子をクエリ可能から簡単に削除する方法はありません。

ただし、できることは、呼び出しを省略して、書き換え(こちら を参照IQueryable)から得られた新しい式に基づいてを再作成することです。queryable.ExpressionOrderBy

于 2012-05-14T21:24:30.393 に答える
2

根本的な原因を取り除くことができない場合は、次の回避策があります。

totalRecordCount = queryable.OrderBy(x => 0).Count();

SQL Server のクエリ オプティマイザーは、この無駄な順序を削除します。ランタイム コストはかかりません。

于 2012-05-14T21:16:34.910 に答える
0

探しているものとはまったく異なることはわかっていますが、DataTimeStampを含む[DataOwnerID]のインデックスを使用すると、クエリのコストを下げることができます。

于 2012-05-15T01:32:46.537 に答える
0

ページングコードを間違って実装したと思います。実際には、ページ化されたデータソースに対して 1 回、合計行数に対して 1 回、データベースに対して 2 回クエリを実行する必要があります。これは、セットアップがどのように見えるかです。

public IList<MyObj> GetPagedData(string filter, string sort, int skip, int take)
{
   using(var db = new DataContext())
   {
      var q = GetDataInternal(db);
      if(!String.IsNullOrEmpty(filter))
         q = q.Where(filter); //Using Dynamic linq

      if(!String.IsNullOrEmpty(sort))
         q = q.OrderBy(sort); //And here

      return q.Skip(skip).Take(take).ToList();
   }
}

public int GetTotalCount(string filter)
{
    using(var db = new DataContext())
    {
       var q = GetDataInternal(db);
       if(!String.IsNullOrEmpty(filter))
         q = q.Where(filter); //Using Dynamic linq

       return q.Count(); //Without ordering and paging.
    }
}

private static IQuerable<MyObj> GetDataInternal(DataContext db)
{
   return 
        from x in db.JournalEventsView 
        where ...
        select new ...;
}

フィルタリングと並べ替えは、Dynamic linq ライブラリを使用して行われます

于 2012-05-14T21:55:50.233 に答える