【问题标题】:WebApi with Odata-V4 and Dapper - Serverside filtering带有 Odata-V4 和 Dapper 的 Web Api - 服务器端过滤
【发布时间】:2016-06-12 08:11:27
【问题描述】:

我们使用带有 OData 和 Dapper 作为 ORM 的 ASP.Net Webapi。对于 GET 请求,我们使用 options 参数对象和它的 filter 参数来构建 Dapper 查询的 SQL 字符串。这适用于列 eq 值等。

但现在我想做一些服务器端分页。这意味着我使用两个过滤器($top 和 $skip)发出请求。例如。 "https://api.server.com/Orders?$skip=100&$top=50。Dapper 向数据库发出了正确的请求,我得到了一个包含 50 个条目的结果作为来自 dapper 的响应。

然后我将这个结果放入 webapi 控制器的 return 语句中,webapi 似乎自己进行过滤。所以它执行从 50 的结果中跳过 100,这导致 0 个条目。

有没有人有同样的问题,并找到了一种方法来阻止 webapi 过滤但将过滤委托给 ORM?编写 ApiControllers 而不是 ODataControllers 是无可替代的,因为我真的很喜欢使用 odata 语法进行过滤。

感谢您的回答!

【问题讨论】:

  • 很想看看您是如何使用 option 参数为 Dapper 构建 SQL 字符串的。
  • 您可以从 ODataQueryOptions.Filter.FilterClause.Expression 中获取顶部的 SingleValueNode,这可以提取为树。最简单的方法是用调试器查看。

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


【解决方案1】:

假设您的 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
}

【讨论】:

  • 感谢您的回复。我的返回参数是一个 IHttpActionResult,但只要我删除 [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)] 属性,它也可以工作。另一方面是我想使用webapi的$select功能,所以看来我必须写两个Get方法。
【解决方案2】:

我们以下面 sn-p 的方式对其进行了修复,这提供了放弃 [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"); 
    } 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多