Как обновить объект OData и изменить его свойства навигации в одном запросе?
Я пытаюсь реализовать то, что я считал простым сценарием, используя службу OData, предоставляемую службами данных WCF (используя приложение OData V3/json;odata=подробный формат полезной нагрузки, на данный момент. Я могу использовать формат JSON Light в будущем). Основной сценарий выглядит так:
у меня есть две сущности:
class Person
{
public int ID { get; set; }
public string Name { get; set; }
public virtual PersonCategory Category { get; set; }
}
class PersonCategory
{
public int ID { get; set; }
public string Description { get; set; }
public virtual ICollection<Person> People { get; set; }
}
теперь, я хочу создать простую страницу редактирования для человека. Эта страница редактирования может иметь вход для имени, а также вход или раскрывающийся список для категории человека.
Итак, сценарий идет:
- код загружает человека, используя $expand для категории: GET / api.svc / People (1)?$разверните=категория
- пользователь редактирует как свойство имени человека, так и его категорию.
- код страницы делает один запрос на обновление свойств имени и категории этого человека.
ключ здесь находится в "одном запросе". Это та часть, которую мне трудно найти. документация. Я видел примеры, когда они разделили номер 3 выше на два запроса. Что - то вроде этого (я не помню точный формат-я также не уверен, что вам придется удалить ссылку категории, прежде чем делать PUT):
PATCH /api.svc/People(1) with content: {"Name": "new name" }
PUT /api.svc/People(1)/$links/Category with content: { "url": "/api.svc/Categories(2)" }
но я также слышал, что он сказал, но не продемонстрировал, что можно реализовать это обновление как один запрос с изменением свойства навигации категории, указанного в строке с другими изменениями в сущности Person. Мог кто-нибудь даст мне пример того, как это можно сделать? Кроме того, вы можете показать мне, как это будет сделано с помощью свойства навигации "многие ко многим", в отличие от одного ко многим, которые я описал выше.
и, наконец, в настоящее время я использую подробный формат JSON, V3. Будут ли ваши ответы на вопросы выше отличаться, если я вместо этого использую новый формат JSON light? Если да, то как?
3 ответов
комментарий Пратика был ответом (Пратик, если вы хотите перепечатать это как ответ, я отмечу его как таковой-спасибо!):
вопрос: вы хотите обновить экземпляр категории или вы хотите обновить некоторые свойства экземпляра категории. Нет никакого способа сделать позже, кроме batch. Для первого вы можете сделать что-то вроде: { "Name" : "new name", "Category" : { "__metadata" : { "uri" : "/api.svc / Categories (2)"}}}. Надеюсь, это поможет. – Пратик!--1-->
Я нашел два способа представления свойств навигации inline:
application/json;odata=verbose
- { "Name": "new name", "Category": { "__metadata": { "uri": "Categories(2)" }}}
application/json
- { "Name": "new name", "Category@odata.bind": "Categories(2)" }
вам больше не нужна партия. Вы можете сделать это за один звонок. Вам просто нужно также отправить измененные свойства и позволить репозиторию обрабатывать измененные свойства.
public class Person
{
public string FirstName {get;set;}
public string LastName {get;set;}
public int Age {get;set;}
}
предположим, вы заметили, что первое имя имеет опечатку, Джон, и это должен быть Джон. Вы можете изменить имя и отправить его. Таким образом, у вас есть следующая объектная модель. Вы можете получить это одним из двух способов:
- есть два параметра и set
BodyStyle = WebMessageBodyStyle.Wrapped
- просто создайте объект универсальной модели с двумя свойствами: свойство один имеет тип T, а свойство 2-Список.
таким образом, вы отправите этот json:
[{ FirstName = 'John' }, ['FirstName']]
Теперь на стороне сервера, вы можете делать то, что вам нужно сделать.
Если вы не хотите отправлять измененные свойства, вы можете угадать измененные свойства, выбрав любое свойство, значение которого не является свойством по умолчанию.
{ FirstName = 'John'}
затем вы можете использовать несколько методы, чтобы увидеть, какие свойства изменились:
- пользовательский код в лицо, чтобы убедиться, что каждое свойство не является значением по умолчанию и установить его. Требуется фрагмент кода для каждой сущности.
- отражение, чтобы убедиться, что каждое свойство не является значением по умолчанию. Требуется 1 класс для всех сущностей. Я сделал это еще в 2014 году здесь, в Entity Framework: http://www.rhyous.com/2014/12/01/entityupdater-generic-helper-for-entity-framework/