Delphi Notes Роздуми на тему недоліки датасетів
Нотатки Delphi + Oracle програміста
Роздуми на тему: недоліки датасетів
Даний пост представляє собою роздуми на тему: недоліки TDataSet. Я припускаю, що читач знайомий із тим, що TDataSet – це базовий клас для роботи з наборами даних (НД). Також я припускаю, що читач знайомий з основами програмування додатків до роботи з базами даних (БД).
Delphi пропонує таку схему роботи з НД:
а) TDataSet – до роботи з самим НД;
б) TDataSource – джерело даних, використовується зв'язку НД з візуальними компонентами;
в) зв'язок компонент з НД (для відображення та редагування) через DataSource.
Начебто все красиво.
Найпростіше – це створення форми для редагування конкретного запису: кожен контроль формі пов'язується з конкретним полем НД. Перед редагуванням користувач вибирає запис, а після редагування або зберігає зміни, або скасовує. Робота з конкретним записом не викликає нарікань.
Але коли необхідно працювати з усім набором відразу (для відображення в гриді, для сортування, для вирішення якихось аналітичних завдань) – відразу виникають проблеми-незручності. Причина цих проблем полягає в тому, що перебір записів датастета можливий лише за допомогою курсора, що вказує на поточний (активний) запис. При цьому слід пам'ятати, що якщо з датасетом пов'язані візуальні контролі, то в загальному випадку треба робити приблизно таке:
DisableControls/EnableControls необхідно робити, щоб контролі не реагували на зміну поточного запису і не викликали мерехтіння, Bookmark потрібен, щоб після роботи з НД повернутися до запису, з яким працював користувач.
DataSet'и мають властивість – поточний стан. Є проміжнестан – dsBrowse, та багато різних – запис редактрується, шукається, тощо. Причому перехід із одного стану до іншого можливий лише через dsBrowse. А це означає, що якщо НД відкритий на редагування, то пошук цього ж НД вже не можливий. Більше того, якщо я працюю, наприклад, з ієрархічною структурою, то, відкривши запис на редагування, я не можу використовувати цей же НД для вказівки батьківського запису.
Залежно від реалізації спадкоємця від DataSet'у, можна натрапити на додаткові сюрпризи. Наприклад, я стикався з тим, що робота з поточним записом здійснюється через певний буфер. Тобто. Перехід від запису до запису викликає копіювання полів запису до буфера, і програміст працює з даними з буфера (а не безпосередньо з даними запису). З одного боку – це захист від випадкового запису набір даних. Але з іншого – це призводить до неприємних затримок під час копіювання.
Втім, інтерфейс класу TDataSet не дозволяє відкрити відразу кілька записів на редагування, доводиться створювати модальні форми, що не дуже красиво по відношенню до користувача.
Описані проблеми – це панацея. Всі ці неприємності або вирішуються обхідними шляхами, або їх можна ігнорувати: затримки копіювання сьогодні настільки незначні, що простого користувача не помітні; щоб не писати DisableControls/EnableControls, можна створити шаблон коду.
Найголовнішою незручністю в датасеті для мене є поняття поточного (активного) запису. На мій погляд, це поняття треба віднести до гриду (або, можливо, до DataSource'у). Якби так було зроблено від початку, то ми (програмісти) отримали б можливість прозорої навігації з НД. А робота з конкретним записом – адже вона визначається користувачем: саме користувач вибирає рядоку таблиці (або навіть кілька (!) рядків), програмісту логічно запросити у грида виділений рядок (список виділених рядків) та працювати з ними.
На підтвердження сказаного я можу навести простий приклад: згадайте, скільки існує візуальних компонентів для роботи з гридам; найзручніші перед роботою роблять повну копію датасета і працюють з датасетом безпосередньо, або пропонують використовувати “свої” датасети.
Наявність цих недоліків призвела до створення власних механізмів для роботи з НД. Докладно я їх поки що описувати не буду, наведу тільки такий приклад:
Ну і наостанок скажу, що винахід свого велосипеда у нас зайшло досить далеко – написані механізми для роботи з БД, окремо обгортки над компонентом VirtualTreeView для візуалізації даних у вигляді таблиці, та окремо обгортки над звичайними компонентами введення даних типу TEdit, TCombobox тощо. п. З одного боку, багато самописного коду - про це за один раз не розповісти. Але з іншого боку нам це дає багато бонусів, що в кінцевому підсумку (і я в це вірю) позитивно відбивається на інтерфейсах користувача.