2

76 ユーザーの Users テーブルと UserGroups テーブルがあります。

MVC、OData、汎用リポジトリ、および EF を使用して、ユーザー グループに基づいてフィルタリングするときにデータ取得を最適化しようとしています。

/api/Users?$filter=USERGROUPS/any(usergroup: usergroup/ID eq 'Group1')

クライアント側では、適切なユーザー数 - 71 (OData が結果に基づいてフィルタリングしているため) を取得しますが、実際のクエリから返されるレコードの数を制限したいと考えています。すべてのレコードを返してからフィルター処理したくありません (非常に大きなデータ セットには最適ではありません)。

私のAPIコントローラーメソッドは次のとおりです。

    [Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IQueryable<USER> Get()
    {
        var unitOfWork = new ATMS.Repository.UnitOfWork(_dbContext);

        var users = unitOfWork.Repository<USER>()
                              .Query()
                              .Include(u => u.USERGROUPS)
                              .Get()
                              .OrderBy(order => order.USERNAME);

        unitOfWork.Save();      // includes Dispose()

        return users.AsQueryable();
    }

この投稿で次のことを読みました。

エンティティ フレームワークは、要求に基づいて動的クエリを作成します。

ただし、SQL Server プロファイラーを使用すると、実行されるクエリはフィルター処理されたクエリではなく、すべてのレコードを要求します。

クエリに .Take() を追加しても、ページングの目的で返される実際のレコード数も必要になるため、目的の結果は得られません。

ODataQueryOptions を使用していくつかのプロパティを取得することを考えていましたが、それも正しくないようです。

達成しようとしていることに関連して、Unit of Work と Repository の実装が正しくありませんか?もしそうなら、どうすれば修正できますか?

4

1 に答える 1

0

シンプル - Queryable 属性 [Queryable(PageSize=10)] のページ サイズを設定するだけです。

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options#server-paging

オプションを適用する場所をEFに伝えれば、それは機能します。このような :

    //[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IQueryable<USER> Get(ODataQueryOptions<USER> options)
    {

        var users = options.ApplyTo(_dbContext.Set<USER>()
                              .Query()
                              .Include(u => u.USERGROUPS)
                              .Get()
                              .OrderBy(order => order.USERNAME));

        return users;
    }

オプションを最後の行「users.AsQueryable()」に適用しようとしたため、コードは機能しませんでした。実際に起こったことは、EF が完全なデータセットをプルし、クエリを最後の行に適用したことです (そのメモリ内コレクションです)。そのため、「フィルター」が SQL に渡されていないことがわかりませんでした。

そのメカニズムは、EF がコード内で見つけた IQueryable コレクションにクエリを適用しようとするようなものです (どのようにして正しい行を見つけるのかという疑問が残ります)。

于 2013-08-07T17:45:41.310 に答える