我们将ASP.Net Webapi与OData和Dapper一起用作ORM。对于GET请求,我们分别使用options参数对象的filter参数为Dapper查询构建SQL String。这适用于列eq值等。
但现在我想做一些服务器端分页。这意味着我使用两个过滤器($ top和$ skip)发出请求。例如。 “https://api.server.com/Orders?$ skip = 100& $ top = 50.Dapper向db发出正确的请求,我得到一个包含50个条目的结果作为dapper的响应。
然后我将此结果提供给webapi控制器的return语句,webapi似乎自己进行过滤。因此它执行从50的结果中跳过100,这导致0个条目。
有没有人遇到同样的问题,并找到了一种方法来阻止webapi过滤,但是将过滤委托给ORM?编写ApiControllers而不是ODataControllers是不可取的,因为我真的想使用odata语法进行过滤。
感谢您的回答!
答案 0 :(得分:2)
假设您的API操作的返回类型是IQueryable,那么框架将对从数据库返回的任何数据应用查询过滤器,因此我们将查询结果包装到PageResult并返回它,它将不会再次应用过滤器。示例代码如下 -
public PageResult<Orders> GetOrdersPage(ODataQueryOptions<Orders> queryOptions)
{
// Parse queryOptions to get Top and Skip
var top = queryOptions.Top.RawValue;
var skip = queryOptions.Skip.RawValue;
//Call the dataaccess method and then get Querable result
var queryResults = dataAccess.GetOrders(top,skip).AsQuerable<Orders>();
//Return Page result
return new PageResult<Orders>(queryResults, new URI("Next page URI"), 1234); //1234 - is total count of records in table
}
答案 1 :(得分:1)
我们以下面的代码片段的方式修复了它,这提供了在[EnableQuery]属性上放弃的解决方案:
public async Task<IHttpActionResult> Get(ODataQueryOptions<vwABC> options)
{
if(options != null && options.SelectExpand != null)
{
options.Request.ODataProperties().SelectExpandClause = options.SelectExpand.SelectExpandClause;
}
if(options != null && options.Count != null && options.Count.Value == true)
{
options.Request.ODataProperties().TotalCount = await base.GetCount("vwABC", options);
}
return await base.Get(options, "vwABC");
}