Могу ли я изменить ODataQueryOptions, используемые для запроса моего ODataController?

Обновить

проголосуйте здесь на User Voice, чтобы устранить неоднозначность.


Я написал OData WebAPI контроллер, наследующий от 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 добавляется в OrderBy собственность ODataQueryOptions перешел в метод.

Эта проблема

Это изменение не влияет на оператор, сгенерированный контроллером. Обработка продолжается, как будто я ничего не изменил и любой OrderBy применяется к ManyColumns сущность заменяется оригиналом OrderBy указано в $orderby параметр исходного запроса.

При дальнейшем осмотре кажется, что ODataQueryOptions вероятно предназначен быть неизменным. Большинство его свойств имеют только get аксессоры.

Вопрос

Я только что неправильно использовал неудачу в реализации OrderByQueryOption?

Есть ли способ изменить ODataQueryOptions что будет применяться к запросу, позже в конвейере?

3 ответа

Решение

Вы должны удалить атрибут [Queryable].

Согласно http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options, вы должны использовать Queryable или манипулировать ODataQueryOptions вручную., Веб-API заполняет ODataQueryOptions из строки запроса URI, после чего можно (предположительно) изменить эти параметры.

Внизу страницы они реализуют то, что действительно похоже на решение вашей проблемы. Они реализуют пользовательский атрибут MyQueryable, который применяет пользовательский упорядоченный валидатор. Возможно, вам не удастся изменить запрос во время проверки, но вы можете переопределить реализацию атрибута ApplyQuery, чтобы ввести требуемое предложение order-by.

Если у вас есть ODataQueryOptions в качестве параметра метода, это означает, что вы хотите обрабатывать параметры самостоятельно. Так что попробуйте это:

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

По умолчанию все запросы упорядочены по PrimaryKey таблицы, если не указан $orderby

Этот код не работает, всегда порядок по первичному ключу

[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, если он указан

Другие вопросы по тегам