Odata v4 - $ развернуть, а затем сгладить результат

Цель: расширить объект и спроецировать вложенное свойство на корневой выбор вместе с другими реквизитами.

Имея следующие отношения:

public class Product {
   public string Barcode { get; set; }
   public double Price { get; set; }
   public Category Category { get; set; }
}

public class Category {
   public string Name { get; set; }
}

Я хотел бы сделать прогноз, который приведет к следующему:

{
   "@odata.context": "http://localhost/odata/$metadata#Product",
   "value": [
      {
         "Price": 500,
         "Name": "Meat Products" // this is category name, ideally would be to rename it to CategoryName
      }
   ]
}

Где в настоящее время я получаю это:

{
   "@odata.context": "http://localhost/odata/$metadata#Product",
   "value": [
      {
         "Price": 500,
         "Category": {
            "Name": "Meat Products"
         }
      }
   ]
}

Используемый запрос следующий:

/odata/Product?$expand=Category($select=Name)&$select=Price

Я бы ожидал написать такую ​​​​проекцию:

/odata/Product?$expand=Category&$select=Price,Category/Name as CategoryName

or

/odata/Product?$expand=Category&$select=Price,Category($select=Name as CategoryName)

or

/odata/Product?$expand=Category&$select=Price,Category($select=Name)

Это достижимо? Благодарю вас!

P.S. Одата версии 4.


person Cristian E.    schedule 15.11.2016    source источник


Ответы (1)


Это недостижимо с семантикой запроса odata v4. Как видите, тело ответа содержит строку:

"@odata.context": "http://localhost/odata/$metadata#Product"

Это означает, что вся полезная нагрузка ответа представляет собой экземпляр типа «Продукт». Предположим, что свойство 'CategoryName' не существует для этого типа, невозможно дать указание службе динамически добавить его с помощью предложения 'AS'. И ключевое слово «AS» также не существует в стандартной спецификации запроса OData.

Однако действительно допустимо возвращать дополнительное свойство помимо метаданных, см. Ссылка.

Клиенты ДОЛЖНЫ быть готовы к получению дополнительных свойств в сущности или экземпляре сложного типа, которые не объявлены в метаданных, даже для типов, не помеченных как открытые.

Таким образом, в этом случае служба может просто вернуть в ответ дополнительное «виртуальное» свойство «CategoryName». (Если вы являетесь владельцем службы, вы можете обновить логику ответа и внести изменения.) Это может быть поведением службы, а не реакцией на определенный запрос клиента.

person Karata    schedule 21.11.2016
comment
Спасибо. Теперь я вижу причину этого ограничения. Добавление виртуального реквизита, вероятно, не будет лучшей идеей в моем случае, поскольку API используется разными потребителями с разными $expands. Хотя немного расстраивает, что нет возможности сделать проекцию с окончательным $select. Похоже, это просто .Select и приведено к типу анонимного объекта, но я могу ошибаться. - person Cristian E.; 21.11.2016
comment
Вы можете сделать это, сделав свой объект данных OpenType, а затем вы можете вручную вставить дочерние свойства в пакет DynamicProperties вашего теперь открытого объекта. Но есть ли хороший аргумент для этого? Я не уверен... как только вы вручную передаете вывод для операции GET, теперь вы должны вручную проанализировать любой POST или PATCH, который возвращает клиент, если вы намерены поддерживать клиент, изменяющий предоставленную вами проекцию. Я обнаружил, что гораздо проще просто обновить клиенты для работы с вложенной структурой, хотя у вас может не быть такой гибкости. - person Chris Schaller; 23.11.2016