WebAPI OData $跳过自定义IQueryable double应用

Bil*_*rry 7 c# iqueryable odata asp.net-web-api

我已经实现了一个通过WebAPI OData端点公开的自定义IQueryable.控制器的Get()结构相当标准:

[EnableQuery(
    AllowedQueryOptions = AllowedQueryOptions.Count
                          | AllowedQueryOptions.Filter
                          | AllowedQueryOptions.OrderBy
                          | AllowedQueryOptions.Skip
                          | AllowedQueryOptions.Top)]
[ODataRoute]
public PageResult<Foo> Get(ODataQueryOptions<Foo> queryOptions)
{

    var bars = new QueryableData<Foo>(_provider);

    var result = ((IQueryable<Foo>)queryOptions
        .ApplyTo(bars,
            new ODataQuerySettings(new ODataQuerySettings { EnableConstantParameterization = false, EnsureStableOrdering = false }))).ToList();
    var count = _provider.Count;
    return new PageResult<Foo>(result, null, count);
}
Run Code Online (Sandbox Code Playgroud)

我看到的奇怪的行为是,在返回PageResult后应用查询字符串中的OData $ Skip.例如:

  • 如果查询字符串包含?$ top = 10&$ skip = 10,则不会返回结果.
  • 如果查询字符串包含?&top = 12&skip = 10,则会返回(2)结果.

我想要做的是阻止框架将Skip应用于我的结果集,因为查询提供程序已经实现了跳过.是否有ODataQuerySettings可以设置为防止跳过此双重应用程序?

编辑:进一步调查,当我从查询字符串skip(和top)函数中删除$ count = true时,按预期方式.这让我相信我实现$ count = true的方法是不正确的.从我的调试会话中可以看出,当$ count = true在查询选项中时,queryable将表达式树应用于它两次,一次返回类型为long,然后再次没有包装countlong表达式.我已尝试在第一次传递时返回计数,然后在第二次传递时返回正确的查询,但这会导致跳过表达式的延迟应用.这里似乎有一些非常基本的东西.

Bil*_*rry 7

在阅读Github问题列表时,我遇到了这篇文章:OData PageResult方法在使用EnableQuery属性#159时忽略count参数.似乎是问题的结果是EnableQuery Attribute和参数化的Get构造函数组合使用ODataQueryOptions.使用这两个意味着您将实现构造函数查询选项,应用查询表达式,然后框架将应用它可以在应用属性的方向上的过滤器; 因此,重复使用像skip,top和orderby这样的东西.

  • 对于其他阅读本文的人感到困惑,这导致我在我的方法上取消了 `[EnableQuery]` 属性,并在我的方法参数中加入了 `ODataQueryOptions`,事情就开始工作了。 (2认同)