WebApi与Odata-V4和Dapper - Serverside过滤

时间:2016-02-29 10:18:08

标签: c# asp.net-web-api odata dapper

我们将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语法进行过滤。

感谢您的回答!

2 个答案:

答案 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"); 
    }