Simple.Odata.Client - объект исправления Odata, отправляющий только измененные свойства на сервер
Я использую Simple Odata Client для выполнения операций CRUD в приложении WPF.
У меня есть родитель и дочерний объект:
public class Order
{
public int OrderId{get;set;}
public int Description{get;set;}
public ObservableCollection<OrderLine> OrderLines {get;set;}
}
public class OrderLine
{
public int OrderId{get;set;}
public int OrderLineId{get;set;}
public int ItenId{get;set;}
public int ItemDescription{get;set;}
public virtual Order Order {get;set;}
}
А у меня есть класс для выполнения грубых операций:
public class ManageOrders
{
//Implements INotifyPropertyChanged
Public Order Order;
public void Get()
{
this.Order = packages = await client
.For<Order>()
.ByKey(1001).
.Expand(x.OrderLines).
.FindEntriesAsync();
}
public void Save()
{
if("NEW")
{
// Add new item and save
}
if("MODIFIED")
{
// save modified item
}
}
public void Delete()
{
//Delete
}
}
Я связываю свойства родительского объекта с элементами управления заголовка.
TextBox.Text = Order.Description;
и дочерний объект для DataGrid.
DataGrid.ItemSource = Order.OrderLines;
Когда я нажимаю кнопку GET, Order будет выбран из БД. Затем я изменяю данные в Order и OrderLines. Затем я удаляю OrderLine и добавляю две новые OrderLines.
Как я использую ObservarbleCollection
изменения будут автоматически добавлены в исходный код из пользовательского интерфейса.
требование
Когда я нажимаю кнопку SAVE, все изменения должны быть отправлены на сервер. (Пакетный запрос является предпочтительным).
Вопрос
Как я могу отправлять только измененные сущности на сервер через запрос PATCH, не отправляя неизмененные свойства как в заголовке, так и в строках?
1 ответ
Здесь вы просите IMO - Святой Грааль веб-сервисов и клиентских платформ.
Патч в OData позволяет легко и просто получать и обрабатывать только измененные свойства объекта.
Однако клиент должен правильно сформировать пакет данных, что можно сделать одним из двух способов:
Перед отправкой клиент должен сравнить данные для отправки с последними полученными данными, чтобы определить, какие свойства изменились.
Если данные на клиенте обернуты в какую-либо модель представления, модель представления может отслеживать (или наблюдать) изменения, внесенные в свойства.
Затем при отправке клиентская сторона должна использовать эту информацию для построения дельты графа объектов.
Вы не включили какую-либо информацию о том, как вы генерируете свои URI, в бэкэнд-сервис, поэтому я не хочу догадываться, но какой бы ни был механизм, необходимо будет реализовать одну из двух вышеупомянутых стратегий.
Если ваш бэкэнд является службой OData v4, то вам может пригодиться пакет OData Client. См. Клиентская библиотека OData для.NET и следующее для создания графов объектов на стороне клиента: Генератор клиентского кода OData v4. Вы можете использовать это против любого сервиса, который реализует спецификацию OData v4, не только когда вы управляете кодом для бэкэнда.
Поддерживает несколько режимов пакетирования, поскольку пакетирование часто реализуется по-разному в реализациях OData v4. По этой причине я оставил пакетное обсуждение в этом обсуждении, но знаю, что оно изначально поддерживается этими библиотеками и работает довольно хорошо.
Пример использования сгенерированных классов см. В следующем вопросе SO: Как правильно вызывать patch из клиента odata в web api 2 или выполните один из моих модульных тестов:
[TestMethod]
public void TestPatch()
{
var client = ArcoCloud.Gateway.Client.Runtime.GetGatewayClient();
var changeTracker = new Microsoft.OData.Client.DataServiceCollection<ArcoCloud.Gateway.Client.ArcoCloud_DataModel.Device>(client.Devices);
// just change device 96
var device = changeTracker.Single(d => d.Id == 96);
device.Notes = "This is a test note to check if patch works natively";
client.SaveChanges();
/* Traced in Fiddler4
PATCH: {
"@odata.type": "#ArcoCloud_DataModel.Device",
"Notes": "This is a test note to check if patch works natively"
}*/
}
Обратите внимание, что для того, чтобы клиент отправлял только измененные свойства, используется Microsoft.OData.Client.DataServiceCollection, который наследуется от ObservableCollection, но имеет дополнительные преимущества, заключающиеся в том, что он отслеживает изменения объектов в своем запросе. см. класс DataServiceCollection.
Если вы используете клиентскую библиотеку OData и сгенерированные классы, вы можете легко запросить службу данных без DataServiceCollection, но если вы это сделаете, обновления будут помещать весь объектный граф. Вы также найдете синтаксис для сохранения изменений довольно многословным и сложным в использовании. Это сделано специально, чтобы написать ответ, вы должны использовать DataServiceCollection. Инфраструктура предлагает простой механизм запросов, позволяющий упростить процессы в ваших приложениях. Запрос / просмотр / фильтрация данных могут быть изолированы от кода, который окно редактирования данных может использовать для загрузки и сохранения своих данных.
Это официальный способ MS взаимодействовать со службами OData v4 из кода C#. Прелесть шаблонов T4 в том, что вы можете настроить шаблон там, где это необходимо, или расширить сгенерированные частичные классы, чтобы ваша бизнес-логика не переопределялась при повторном создании классов.
Вы можете использовать свой собственный механизм для поддержки этого, если хотите, просто запомните две опции: либо отслеживайте изменения по мере их возникновения, либо используйте сравнение перед сохранением, чтобы определить, какие поля изменились.