Модель EDM OData — автоматическое расширение вложенного типа сущности

#asp.net-web-api #odata

Вопрос:

Я использую OData v4, и модели настроены с помощью EdmModel Builder для нашего веб-API .NET.

У меня есть две модели, определенные следующим образом:

 public class Customer
{
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
    public string Category { get; set; }
    public Customer OrderCustomer { get; set;}
}   
 

Эти модели имеют соответствующие контроллеры и зарегистрированы следующим образом:

 builder.EntitySet<Customer>("Customers")
          .EntityType
          .HasKey(x => x.CustomerId);

builder.EntitySet<Order>("Orders")
          .EntityType
          .HasKey(x => x.OrderId)
          .Expand(
            maxDepth: 2,
            expandType: SelectExpandType.Automatic,
            properties: nameof(Order.OrderCustomer));
 

Я могу отправлять запросы OData на обе эти конечные точки следующим образом:
/Customers/{Id} и. /Orders/{Id}

Я ожидаю , что при запросе Orders вложенный Customers набор объектов будет автоматически расширяться с тех пор, как я expandType: SelectExpandType.Automatic установил набор Order объектов. Однако я не могу заставить CustomerOrder свойство автоматически расширяться Customer , и мне приходится вызывать запрос с параметром расширения:

/Orders/{Id}?$expand=OrderCustomer .

Я думаю, это связано с тем, что оба Customer и Order зарегистрированы как наборы сущностей, поэтому OData ожидает, что будет предоставлен параметр расширения, если они вложены. Есть ли способ заставить OrderCustomer свойство автоматически расширяться (т. Е. Без необходимости указывать параметр расширения)? Мое понимание моделей OData/ Edm довольно элементарно, поэтому я ценю любую помощь.

Ответ №1:

Ваша конфигурация fluent верна для OData v4, которая будет работать как для запросов коллекции, так и для запросов элементов.

Если это не работает для вас, есть 3 возможных проблемы:

  1. Похоже, вы не используете соглашение об URL-адресах OData v4 для запросов элементов, в v4 ожидаемый URL-адрес:
     /Orders({Id})
     

    Это ставит под сомнение то, как вы изменили маршрутизатор для поддержки синтаксиса v3, существует множество вариантов реализации маршрутов v3, поэтому возможно, что изменения, внесенные в этой области, могут повлиять на то, как применяется расширение и выбор по умолчанию, или если это должно применяться.

  2. Возможно, вы не включаете навигационные данные в свой запрос данных. Если данные не извлекаются из хранилища данных, то само собой разумеется, что их не будет в наборе выходных записей. Если вы вручную используете ODataQueryOptions.ApplyTo() для применения запроса пользователя к вашему запросу, то при этом не будет учитываться конфигурация модели, будут применены только параметры запроса, указанные вызывающим пользователем.
  3. Вызывающий абонент может указывать Пустое $expand= значение, которое отменит автоматическую настройку. Даже если исходящий вызывающий абонент не указал никаких параметров запроса, для API OData достаточно часто используется стандартное или настраиваемое промежуточное программное обеспечение, которое может манипулировать строками запроса запроса. Чтобы убедиться, что URL-адрес не изменен, зарегистрируйте его в обработчике GET метода и убедитесь $expand , что он не указан.
    • Как и в предыдущем пункте, ODataQueryOptions параметр в вашем GET методе не должен показывать никакого значения для параметра SelectExpand , если вы хотите, чтобы применялась автоматическая конфигурация.

Наконец, последнее, что нужно проверить, — это то, что вы не переопределили значение по умолчанию EnableQueryAttribute . Если вы реализовали свою собственную пользовательскую реализацию EnableQueryAttribute , убедитесь, что вы все еще вызываете базовую реализацию, чтобы правильно применить значения по умолчанию ODataQueryOptions И схему к базовому IQueryable результату.