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
    }   
}

введите здесь описание изображения

Я привязываю свойства объекта Parent к элементам управления заголовком.

TextBox.Text = Order.Description;

и дочерний объект для DataGrid.

DataGrid.ItemSource = Order.OrderLines;

Когда я нажимаю кнопку ПОЛУЧИТЬ, заказ будет получен из БД. Затем я меняю данные в Order и OrderLines. Затем я удаляю строку заказа и добавляю две новые строки заказа.

Поскольку я использую ObservarbleCollection, изменения будут автоматически добавлены в исходный код из пользовательского интерфейса.

Требование

Когда я нажимаю кнопку СОХРАНИТЬ, все изменения должны быть отправлены на сервер. (Пакетный запрос предпочтительнее).

Вопрос

Как я могу отправить на сервер только измененные объекты через запрос PATCH, не отправляя неизмененные свойства как в заголовке, так и в строках?


person Rahul    schedule 10.03.2017    source источник


Ответы (1)


То, что вы просите здесь, - это IMO Святой Грааль веб-сервисов и клиентских фреймворков.

Исправление в OData делает возможным и простым получение и обработку только измененных свойств объекта.

Однако клиент должен правильно построить пакет данных, что можно сделать одним из двух способов:

  1. Перед отправкой клиент должен сравнить данные для отправки с данными, которые были получены последними, чтобы определить свойства, которые изменились.

  2. Если данные на клиенте заключены в какую-либо модель представления, модель представления может отслеживать (или наблюдать) изменения, внесенные в свойства.

Затем при отправке клиентская сторона должна использовать эту информацию для построения дельты графа объекта.

Вы не включили какую-либо информацию о том, как вы генерируете свои URI для серверной службы, поэтому я не хочу гадать, но какой бы ни был механизм, необходимо будет реализовать 1 из двух вышеперечисленных стратегий.

Если ваша серверная часть представляет собой службу 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 заключается в том, что вы можете настроить шаблон там, где это необходимо, или расширить сгенерированные частичные классы, чтобы ваша бизнес-логика не переопределялась при повторном создании классов.

Вы можете создать свой собственный механизм для поддержки этого, если хотите, просто запомните два варианта: либо отслеживать изменения по мере их возникновения, либо использовать сравнение перед сохранением, чтобы определить, какие поля были изменены.

person Chris Schaller    schedule 24.03.2017
comment
Приносим извинения за то, что не видим тег OData.Simple.Client. Эта библиотека позволяет вам использовать команду PATCH для обновлений, но в более ранних версиях она по-прежнему отправляла весь граф объектов в патче. Когда я понял это, я переключился на Microsoft.OData.Client :) - person Chris Schaller; 24.03.2017
comment
Спасибо за ваши усилия. Я уже использую генератор клиентского кода OData v4. Но я не уверен, что смогу использовать это в Xamarin. Между тем Simple.Odata.Client — это библиотека PCL. Вот меня это и заинтересовало.. - person Rahul; 24.03.2017