Ієрархічна (деревовидна) модель даних містить набір записів з співвідношенням батько-нащадок. Глибина вкладеності не обмежена.
Ієрархічна модель представлена типом об'єкта !Tree
.
Для правильної роботи дерева кожний запис повинен мати три обов'язкових поля:
!Id
- ідентифікатор запису!ParentId
- ідентифікатор батьківського запису.!Items
- масив дочірніх полів.Зверніть увагу. Для формуваня наборів даних зазвичай використовується механізм рекурсивних запитів T-SQL (CTE) - Common Table Expressions) та оператор WITH. Детальніше в документації Microsoft.
Дерева можуть завантажуватися як статично (все дерево за один запит), так і динамічно (lazy loading), коли гілки дерева заповнюються з бази даних тільки у випадку, якщо користувач (або програма) розкриває цю гілку.
Роботу з ієрархічною моделлю простіше за все продемострувати на прикладі.
Нехай маємо таблицю Agents
наступного вигляду:
Id | Parent | Name |
---|---|---|
10 | null | Agent 1 |
20 | null | Agent 2 |
100 | 10 | Subagent 1.1 |
110 | 10 | Subagent 1.2 |
200 | 20 | Subagent 2.1 |
210 | 20 | Subagent 2.2 |
Статичне дерево заповнюється одразу повністю за одне звернення до БД. Запит, що формує дані для моделі дерева, буде виглядати наступним чином:
При обробці цього набору створюється простий масив Agents
елементів типу TAgent
.
В кожному елементі цього масива буде масив Items
, який буде заповнено дочірніми елементами.
Батьківський елемент визначається властивістю з модифікатором ParentId
. Зверніть увагу, що
це поле не має імені властивості, тому воно не потрапить в результуючу модель.
В результаті обробки отримаємо таку модель (службові властивості для спрощення не показані):
Для роботи з такою моделлю частіше за все використовується елемент керування TreeView.
Наприклад (XAML):
Динамічне дерево заповнюється по мірі того, як користувач відкриваї певні гілки дерева.
При роботі з динамічним деревом достатньо повернути з процедури завантаження тільки верхній рівень дерева.
Однак для того, щоб система знала, які елементи можна розкрити, потрібно мати в моделі ще одну службову
властивість з спеціальним типом !HasChildren
. Якщо така властивість встановлена, то система вважає, що цей
елемент має дочірні і показує відповідні елементи інтерфейса користувача.
Зверніть увагу, что така властивість, не дивлячись на те, що вона службова, обов'язково повинна мати ім'я, оскільки робота з нею ведеться на клієнтському боці.
Коли користувач намагається розкрити такий елемент дерева, викликається збережена процедура з суфіксом
.Expand
, яка повинна повернути дочірні елементи для цього вузла.
Далі процес повторюється рекурсивно.
Процедура верхнього рівня може повернути такий набір:
Тоді при спробі розкриття дерева викличеться процедура .Expand
, яка повинна повернути
елементи наступного рівня дерева.
Елементи дерева в моделі даних реалізують інтерфейс ITreeElement
і
мають деякі додаткові властивості. Детальніше....