带有 Odata-V4 和 Dapper 的 Web Api - 服务器端过滤
WebApi with Odata-V4 and Dapper - Serverside filtering
我们使用 ASP.Net Webapi 与 OData 和 Dapper 作为 ORM。对于 GET 请求,我们分别使用选项参数对象和它的过滤器参数来为 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 语法进行过滤。
感谢您的回答!
假设您的 API 操作的 return 类型是 IQueryable,那么框架将对从数据库 return 编辑的任何数据应用查询过滤器,所以让我们包装查询结果进入 PageResult 和 return 它,它不会再次应用过滤器。示例代码如下-
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
}
我们通过下面的代码片段修复了它,这提供了放弃 [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");
}
我们使用 ASP.Net Webapi 与 OData 和 Dapper 作为 ORM。对于 GET 请求,我们分别使用选项参数对象和它的过滤器参数来为 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 语法进行过滤。
感谢您的回答!
假设您的 API 操作的 return 类型是 IQueryable,那么框架将对从数据库 return 编辑的任何数据应用查询过滤器,所以让我们包装查询结果进入 PageResult 和 return 它,它不会再次应用过滤器。示例代码如下-
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
}
我们通过下面的代码片段修复了它,这提供了放弃 [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");
}