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 つだけです。
これを適切に機能させるために何が欠けていますか?他の誰かがこれを経験しましたか?