web-dev-qa-db-ja.com

C#エンティティフレームワークのページング

複雑なLinqクエリの行数と数百万のレコードを取得する方法はありますかwithoutデータベースを2回ヒットするか、書き込みます2つの別々のクエリ??

私自身の提案があるかもしれません。ストアドプロシージャを作成しますが、MSSQLではなくMySQLが得意です。

より良い提案があれば素晴らしいでしょう。また、Microsoftがこの機能をエンティティフレームワークに追加する作業を行っているかどうかを誰かが知っている場合。

14
Jason Foglia

Take()関数を使用することをお勧めします。これを使用して、linqクエリまたはリストから取得するレコードの数を指定できます。例えば

List<customers> _customers = (from a in db.customers select a).ToList();
var _dataToWebPage = _customers.Take(50);

私はMVCアプリで同様の手法を使用して、セッションに_customersリストを書き込み、ユーザーが2、3ページなどをクリックしたときに、このリストを使用してさらにページネーションクエリを実行します。これにより、複数のデータベースヒットが節約されます。ただし、リストが非常に大きい場合は、それを書き込むこともセッションはおそらく良い考えではありません。

ページネーションには、Skip()関数とTake()関数を一緒に使用できます。たとえば、データの2ページ目を取得するには:

var _dataToWebPage = _customers.Skip(50).Take(50);
10
Tim Newton

何百万ものレコードを表示する一般的な方法は、単にすべてのページを表示しないことです。考えてみてください。たとえば、1ページあたり20または100のアイテムなど、数百万のレコードがある場合、数万のページがあります。それらすべてを表示することは意味がありません。現在のページをロードして、次のページへのリンクを提供するだけです。または、たとえば100〜500レコードをロードしても、1ページしか表示せず、ロードされたレコード情報を使用して最初の数ページのページリンクを生成することもできます(次のページがいくつあるかを確認してください)。

2

それはSQLサーバー上でとても簡単です。あなたはこのクエリを書くことができます:

select count() over(), table.* from table

count()over()は結果の合計行数を返すため、2つのクエリを実行する必要はありません。コンテキストでraw sqlを実行するか、ビューモデルとして結果を返すdapperを使用する必要があることに注意してください。

私は最近、このCode Projectの記事に触発されました(コピーされました) Entity Frameworkページング

コード:

public async Task<IList<SavedSearch>> FindAllSavedSearches(int page, int limit)
{
    if (page == 0)
        page = 1;

    if (limit == 0)
        limit = int.MaxValue;

    var skip = (page - 1) * limit;

    var savedSearches = _databaseContext.SavedSearches.Skip(skip).Take(limit).Include(x => x.Parameters);
    return await savedSearches.ToArrayAsync();
}

私はEntityFrameworkの経験がなく、パフォーマンスをテストしていないので、注意して使用してください:)

0
jk1990