Порядок обновления однтипных и разнотипных объектов

Порядок обновления объектов

Для того чтобы обновить в хранилище несколько объектов данных, будь они однотипные или разнотипные, следует вызвать метод сервиса данных UpdateObjects с параметром — одномерным массивом (типа DataObject) этих объектов данных. Запросы для всех переданных объектов будут выполнены в единой транзакции.

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

В общем случае сервис данных умеет сам выстраивать порядок запросов на обновление объектов данных. Но возможны ситуации, когда для связанных объектов важен порядок следования объектов в массиве, например:

  • Наличие циклов в графе типов. В частности, при удалении объектов в случае циклических ссылок программист должен не только проконтролировать порядок объектов в массиве, но и осознанно занулить какую-нибудь ссылку.
  • Удаление объекта и его мастера в одной транзакции. Важен порядок, в котором объекты пришли в сервис данных.
  • Ситуация, когда агрегатор и детейл имеют мастера одного типа.
  • Другие варианты при наличии связанных объектов с разными статусами, т.е. когда часть объектов добавляется, часть - обновляется, часть - удаляется.

Общая рекомендация

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

и есть объекты: a, m1, m2, m3, то правильный массив будет такой:

new DataObject[]){m3,m2,m1,a}

Ошибочное вычисление статуса объекта после обновления

Если указанное правило размещения мастеров в массиве не соблюдается, возможно ошибочное вычисление статуса объекта после обновления, если до обновления объекты имели статус Сreated. А именно: создан объект и мастера для него (оба объекта со статусом Сreated), объект отправлен на обновление. Но в результате получается следующее:

GetStatus() == ObjectStatus.Altered 

и в копии данных мастера нет.

Например, создан следующий граф объектов с мастером и агрегатором:

в UpdateObjects следует передавать объекты в определенном порядке: мастеровой объект (Модель) должен быть добавлен раньше, чем детейловый объект (Автомобиль), использующий его:

    var objects = new List<DataObject>();

    var модель = new Модель { Наименование = "ВАЗ" };
    var клиент = new Клиент { Фамилия = "Иванов", Имя = "Петр" };
    var авто = new Автомобиль { ГодВыпуска = 2012, /*Клиент = клиент, - агрегатор проставится автоматически*/ Модель = модель };
    клиент.Автомобиль.Add(авто);
    objects.Add(модель);  // мастер добавляем раньше
    objects.Add(клиент);

    var dataObjects = objects.ToArray();
    ds.UpdateObjects(ref dataObjects);

В противном случае детейловые объекты (Автомобиль) могут иметь статус Altered из-за некорректной копии данных.

Замечание: Если сервис данных является наследником SQLDataService для решения проблемы неверного автоматического определения сервисом данных порядка обработки объектов предлагается использовать метод UpdateObjectsOrdered, который выполняет обновление объектов последовательно в том порядке, в котором они приходят в этот метод.