Зверніть увагу, що модель оновлюється цілком за один виклик збереженої процедури. Для передачі даних широко використовуються табличні параметри SQL-сервер.
Оновлення моделей виконується наступним чином.
Спочатку клієнт надсилає всю модель на сервер.
Система знаходить ім'я моделі для відповідні дії і викликає збережену процедуру з суфіксом .Metadata. Ця процедура повертає декілька наборів з пустим вмістом. Імена полів в цих наборах визначають правила, яким чином перетворювати вміст отриманої з клієнта моделі в параметри збереженої процедури оновлення моделі.
Система перетворює отримані сирі дані в набір таблиць, використовуючи отримані метадані.
Викликається процедура з суфіксом .Update і їй передаються перетворені таблиці.
Ім'я першого поля кожного набору завжди складається з трьох елементів, розділених символом '!'.
Решта полів набору являють собою властивості в моделі, і відповідно поля в табличній змінній.
Кількість табличних параметрів в процедурі .Update (не враховуючи попередньо визначених) завжди буде дорівнювати кількості наборів, які повернула процедура .Metadata.
Розглянемо процедуру оновлення документа. Працюючий приклад таблиць і збережених процедур можна найти на GitHub
Визначимо табличні типи
Перший тип буде відповідати таблиці a2v10sample.Documents, а другий таблиці a2v10sample.DocDetails.
Процедура отримання метаданих буде мати наступний вигляд:
Вона повертає два набори. Перший набір описує сам документ (в таблиці буде завжди один запис) з усіма потрібними полями. Ця таблиця буде передана в параметр з іменем @Document. Зверніть увагу, що в імені [Document!Document!Metadata] перше слово Document - це ім'я параметра, а друге Document - шлях в моделі, звідки потрібно отримати дані.
Другий набір описує таблицю рядків. В цій таблиці буде стільки ж рядків, скільки і в масиві Document.Rows вихідної моделі. Ім'я параметра - @Rows.
Процедура оновлення буде мати наступний вигляд:
Процедура просто оновлює (або вставляє) документ і його рядки, використовуючи оператор merge. Зверніть увагу, що для отримання ідентифікатора документу (який потрібен для вставки рядків) використовується псевдотаблиця inserted
При заповненні таблиць даних з моделей в таблиці додаються наступні службові поля. Якщо вони будуть визначені в табличних типах, то їх значення будуть заповнені. Ці поля використовуються для зв'язуваня дочірніх записів (бо вони можуть бути новими і їх ідентифікаторів ще може не існувати).
Ім'я | Тип | Опис |
---|---|---|
GUID | uniqueidentifier | Унікальне значення. Використовується спільно з ParentGUID. |
RowNumber | int | Номер рядка в таблиці (починаючи з 1). |
CurrentKey | Різні типи | Поточний ключ в таблицях типу Map. Використовується разом з полем ParentKey дочірньої таблиці. |
ParentId | Різні типи | Ідентифікатор батьківського запису. Ідентифікатор - завжди властивість з іменем Id. |
ParentGUID | uniqueidentifier | Унікальний ідентифікатор батьківського запису (властивість з іменем GUID з батьківської таблиці). |
ParentKey | Різні типи | Ключ батьківського запису (CurrentKey). Використовується для заповнення таблиць типу Map. |
ParentRowNumber | int | Номер рядка батьківського запису (властивість з іменем RowNumber з батьківської таблиці). |
Для того, щоб побачити, які дані приходять в збережену процедуру, можна використовувати наступний фрагмент коду (где @Rows - ім'я табличного параметру):