【问题标题】:Can I change the ODataQueryOptions used for my ODataController's request?我可以更改用于我的 ODataController 请求的 ODataQueryOptions 吗?
【发布时间】:2023-03-08 22:20:02
【问题描述】:

更新

投票here on User Voice 解决歧义。


我编写了一个继承自 ODataController 的 OData WebAPI 控制器。

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 添加到传递给方法的ODataQueryOptionsOrderBy 属性中。

问题

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

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

问题

我是不是误用了 OrderByQueryOption 的实施失败?

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

【问题讨论】:

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


    【解决方案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 的 orderer,或者如果指定了 $orderby 参数中的值

    【讨论】:

    • 所以,我想在指定的$orderby 的末尾添加子句,或者如果没有指定$orderby,则设置一个默认值。
    【解决方案2】:

    您应该删除 [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 子句。

    【讨论】:

    • 这实际上是我最终所做的。这需要做很多额外的工作,但我不得不将全文搜索与服务器端分页结合起来,所以无论如何都必须“手动滚动”SQL。
    【解决方案3】:

    如果你有 ODataQueryOptions 作为方法参数,这意味着你想自己处理选项。所以试试这个:

    return options.ApplyTo(this.context.ManyColumns.AsQueryable());
    

    【讨论】:

    • 但是,这是否会阻止选项在返回后在管道中重新应用?不在我的测试中。
    • 也许如果我放弃了Queryable arttribute 但我也必须执行验证。
    猜你喜欢
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 2010-09-28
    相关资源
    最近更新 更多