Сохранение вложенных сущностей
Last updated
Last updated
В этой статье рассматриваются способы сохранения сущности, имеющей, помимо скалярных полей, табличные данные. Например, поступление, которое имеет дату и номер, а также список товаров:
Данные из карточки позиции поступления передаются на родительскую форму и добавляются в таблицу, откуда отправляются на сервер или передаются в карточку позиции для редактирования.
В базе данных поступление представлено двумя таблицами:
Есть два способа сохранения таких сущностей:
последовательный вызов двух команд, которые отдельно сохраняют скалярные и табличные данные;
создание на форме единого JSON-объекта, который отправляется на сервер одним запросом.
Первый способ заключается в использовании двух последовательных команд. Первая сохраняет скалярные данные и возвращает на форму идентификатор добавленной записи. Вторая сохраняет табличные данные, используя результат выполнения первой команды, в котором хранится идентификатор новой записи.
В примере рассматривается создание нового поступления и не описывается код для сохранения изменений в существующем поступлении.
С необязательным предложением RETURNING
команда INSERT
возвращает значение колонки income_id для добавленной записи. Это значение вернется на форму и будет храниться в результате команды IncomeInsertSaveCommand.
Как вариант, вместо предложения RETURNING
можно использовать функцию currval
для получения текущего значения последовательности. Тогда запрос на сохранение скалярных данных будет иметь вид:
После того, как форма получила результат выполнения команды IncomeInsertSaveCommand, его можно использовать на форме, обращаясь к команде по имени.
В параметре IncomeId обращаемся к результату выполнения команды, а не вызываем ее повторно.
Недостаток такого варианта в том, что если команда сохранения табличных данных упадет с ошибкой, то изменения, внесенные в базу данных первой командой, все равно сохранятся. Таким образом, нарушится целостность данных.
Второй способ заключается в создании на форме JSON-объекта и передаче его одним запросом на сервер.
Для передачи JSON-объекта на сервер используется команда IncomeSaveCommand типа SaveCommand, которая вызывает сохраняющее соединение:
В единственный параметр Model передается результат команды сериализации словаря.
Сам запрос IncomeSaveSqlQuery будет иметь вид:
Результат запроса будет храниться в результате команды IncomeSaveCommand, который можно получить по имени команды и сохранить в параметр формы, чтобы использовать его дальше на форме:
Итоговая команда SaveSequentialCommand будет иметь вид:
Сначала обновляем переменную IncomeDictionaryVariable, а затем сериализуем ее в JSON-объект и передаем на сервер.
Преимущество этого варианта в том, что все данные отправляются на сервер одним запросом и обрабатываются в одной транзакции, что гарантирует целостность данных.
Команда IncomeInsertSaveCommand вызывает с запросом:
Подробнее о функциях для работы с последовательностями в рамках одной транзакции можно почитать в статье .
Например, результат команды можно сохранить в параметр формы, вызвав команду после вызова команды IncomeInsertSaveCommand:
Или сразу использовать в для сохранения табличных данных, который вызывается во второй команде IncomeItemDatabaseTableSaveCommand:
Команда возвращает результат первого SqlQuery типа Insert первого . Если SqlQuery типа Insert не указан в SetDataConnection, то будет возвращаться результат первого SqlQuery типа Update, если такой описан в сохраняющем соединении с данными. Иначе будет возвращаться результат первого SqlQuery типа Delete.
Первое, что нужно сделать - создать объект , в котором описать , которая позже сериализуется в JSON-объект:
Обратите внимание, что у тэга <MyObject>
стоит атрибут ChangeForm
со значением False, чтобы этот объект исключить из проверки свойства самой формы.
Для списка позиций в поступлении используется конструкция с преобразованием массива строк из таблицы в массив словарей.
У тэгов <Object>
и <Parameter>
используется атрибут Refresh
, который определяет, будет ли обновляться значение у тэгов <Key>
и <Array>
, если изменится значение источника. Таким образом, значение объекта IncomeDictionaryVariable не будет обновляться каждый раз, когда изменяется какой-либо источник. Для ручного обновления IncomeDictionaryVariable нужно использовать команду для обращения к set-проперти у объекта Variable:
Для преобразования словаря к JSON-объекту используется команда :