3

更新

在用户语音上投票以解决歧义。


我编写了一个继承自ODataController.

public class ManyColumnsController : ODataController
{
    [Queryable(
        AllowedOrderByProperties = "Aa,Bb,Cc,Dd",
        EnsureStableOrdering = false,
        MaxOrderByNodeCount = 2)]
    public IQueryable<ManyColumn> GetManyColumns(
            ODataQueryOptions<ManyColumn> options)
    {
        // Because I've disabled EnsureStableOrdering,
        // I need to check column "Dd" is always included
        // in the OrderBy option. This will ensure stable ordering.
        if (!options.OrderBy.RawValue.Contains("Dd")
        {
             var entityType = options.Context.ElementType as IEdmEntityType;
             var ddProperty = entityType.DeclaredStructuralProperties()
                 .Single(p => p.Name == "Dd");
             options.OrderBy.OrderByNodes.Add(new OrderByPropertyNode(
                 ddProperty,
                 OrderByDirection.Descending));
        }

        return this.context.ManyColumns;
    }
}

此代码运行,并在传递给方法的属性中OrderByNode添加了一个额外的内容。OrderByODataQueryOptions

问题

此更改对控制器生成的语句没有影响。处理继续进行,就好像我什么都没做一样,任何OrderBy 应用于实体的东西都被原始请求的参数中指定的原始ManyColumns值替换。OrderBy$orderby

在进一步的检查中,它似乎ODataQueryOptions可能是不可变的。它的大部分属性只有get访问器。

问题

我是否只是在实施中滥用了失败OrderByQueryOption

有没有办法修改ODataQueryOptions将应用于请求的,稍后在管道中?

4

3 回答 3

3

您应该删除 [Queryable] 属性。

根据http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options#ODataQueryOptions,您应该使用 Queryable 或手动操作 ODataQueryOptions . Web API 从 URI 查询字符串填充 ODataQueryOptions,之后您可以(可能)更改这些选项。

在页面的下方,他们实现了一些看起来非常接近您的问题的解决方案的东西。他们实现了一个自定义 MyQueryable 属性,该属性强制执行自定义 order-by 验证器。您可能无法在验证期间更改查询,但您可以覆盖属性的 ApplyQuery 实现以注入所需的 order-by 子句。

于 2014-05-15T15:33:33.900 回答
2

如果您将 ODataQueryOptions 作为方法参数,则意味着您要自己处理选项。所以试试这个:

return options.ApplyTo(this.context.ManyColumns.AsQueryable());
于 2014-05-07T10:06:58.970 回答
1

默认情况下,如果没有指定 $orderby,所有查询都是按表的 PrimaryKey 排序的

此代码不起作用,始终按主键排序

[Queryable]
public IQueryable<Coches> GetCoches()
{
return db.Coches.OrderByDescending(c => c.Marca);
}

要覆盖该行为,请在 Queyable 属性中使用此参数

[Queryable(EnsureStableOrdering=false)]
public IQueryable<Coches> GetCoches()
{
return db.Coches.OrderByDescending(c=>c.Marca);
}

前面的代码工作正常,返回值是按 Marca 排序的,或者按 $orderby 参数中的值(如果指定)

于 2014-06-01T09:03:39.790 回答