0

OData と Entity Framework は、OData オプションが EF db コンテキストに渡されてクエリをフィルター処理するという点で、うまく連携すると想定されています。すべてのレコードをフィルタリングするのではなく、ペイロードを膨らませないように、サーバーから要求されたレコードの数のみを返します。

次の URL パスを指定します。

/api/Users?$top=10&$skip=10

次のコントローラ アクションがあるとします。

    [Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IEnumerable<USER> Get(ODataQueryOptions<USER> options)
    {
        var dbContext = new ATMS.DAL.AtmsContext();
        //var ret = options.ApplyTo(dbContext.USERS).Cast<USER>().ToArray();        // returns 10 rows but client sees 0
        var ret = dbContext.USERS.ToArray();                                        // returns all records, filtered results to client

        return ret;
    }

を使用するret = options.ApplyTo(dbContext.USERS).Cast<USER>().ToArray();と、SQL Server Profiler から、適切なクエリが実行され、Entity Framework を介してデータベースから 10 件の結果が返されることがわかります。

によって 10 項目の配列が返されますretが、問題は、クライアントへの応答にデータが含まれていないことです。

{
  "odata.metadata":"http://localhost:59337/api/$metadata#Users","value":[

  ]
}

スキップが指定されていない場合、上位 10 件の結果が返されます。明らかにページングには役に立ちません。

上位 10 件の結果を使用ret = dbContext.USERS.ToArray();するとスキップが適切に適用されますが、すべての結果がデータベースから返され、その後フィルタリングが適用されるためです。これは私が達成しようとしているものではありません。

私の WebApiConfig.cs にはconfig.EnableQuerySupport();.

PageSize属性を追加しても効果はありません:

[Queryable(AllowedQueryOptions = AllowedQueryOptions.All, PageSize = 10)]

戻るIQueryable<User>ことも効果がありません。

戻るPageResult<USER>- 変更なし:

    IQueryable results = options.ApplyTo(dbContext.USERS.AsQueryable(), settings);

    return new PageResult<USER>(
        results as IEnumerable<USER>,
        Request.GetNextPageLink(),
        Request.GetInlineCount());

- より詳しい情報 -

を使用し/api/Users?$top=10&$skip=0て、アクション メソッドの先頭にブレークポイントを設定し、Visual Studio でのデバッグ中に Skip.RawValue を設定して実行を続行すると、期待される 10 個の結果が得られます。

手動で編集されたスキップ値

どういうわけか、結果が追加のスキップの影響を受けているように見えます。これが、結果が表示されない理由である可能性があります。

を使用するhttp://localhost:59337/api/Users?$top=10&$skip=9と、ページ 2 の最後から 2 番目の結果が表示されます。結果は 1 つだけです。

これを適切に機能させるために何が欠けていますか?他の誰かがこれを経験しましたか?

4

1 に答える 1