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