Есть ли какой-нибудь способ в Delphi для кэширования строк с основными данными и одновременной публикации как основных, так и подробных дочерних строк?

Я хочу разместить в памяти некоторые дочерние строки, а затем условно опубликовать их, или не размещать их в базовой базе данных SQL, в зависимости от того, опубликована родительская строка или нет. Мне не нужен полный ORM, но, может быть, просто так:

  1. Пользователь нажимает Добавить доктора. Откроется диалоговое окно "Добавить доктора".
  2. Прежде чем нажать кнопку "ОК" на "Добавить доктора", в диалоговом окне "Добавить доктора" пользователь добавляет одного или нескольких пациентов, которые сохраняются только в памяти.
  3. Пользователь нажимает Ok в окне Добавить доктора. Теперь все пациенты хранятся, плюс новый доктор.
  4. Если пользователь нажал кнопку "Отмена" в окне врача, вся информация о враче и пациенте будет удалена.

Попробуйте, если хотите, мысленно представить, как вы могли бы сделать вышеописанное, используя элементы управления данными Delphi, а также TADOQuery или другие объекты ADO. Если есть способ, не относящийся к ADO, мне это тоже интересно, я просто добавляю ADO, потому что я использую MS-SQL Server и ADO в моих текущих приложениях.

Так у предыдущих работодателей, где я работал недолго, у них был класс под названием TMasterDetail это было специально написано, чтобы добавить вышеизложенное в наборы записей ADO. Иногда это срабатывало, а иногда - не очень интересно и сложно исправить.

Есть ли что-то встроенное в VCL, или какой-либо сторонний компонент, который имеет надежный способ сделать эту технику? Если нет, то о чем я говорю выше, требует ли ORM? Я думал, что многие люди считают ORM "плохими", но приведенный выше пример довольно естественного пользовательского интерфейса, который может встречаться в миллионах приложений. Если бы я использовал стиль работы не-ADO-не-Delphi-db-dataset, вышеприведенное не было бы проблемой практически для любого уровня персистентности, который я мог бы написать, и все же, когда базы данных с первичными ключами используют значения идентичности для связывания в кадр попадают строки мастера и детали, все усложняется.

Обновление: транзакции вряд ли идеальны в этом случае. (Commit/Rollback - слишком грубый механизм для моих целей.)

1 ответ

Решение

Вы задаете два отдельных вопроса:

  1. Как я кеширую обновления?
  2. Как я могу зафиксировать обновления в связанных таблицах одновременно.

Кэшированные обновления могут быть выполнены различными способами. Какой из них лучше, зависит от вашей конкретной ситуации:

Пакетные обновления ADO

Поскольку вы уже заявили, что используете ADO для доступа к данным, это разумный вариант. Вам просто нужно установить LockType в ltBatchOptimistic и CursorType в ctKeySet или ctStatic перед открытием набора данных. Затем вызовите TADOCustomDataset.UpdateBatch, когда будете готовы к фиксации.

Примечание. Основной поставщик OLEDB должен поддерживать пакетные обновления, чтобы воспользоваться этим. Поставщик SQL Server полностью поддерживает это.

Я не знаю другого способа обеспечить связь мастер / подробности при сохранении данных, кроме как последовательно вызывать UpdateBatch для обоих наборов данных.

Parent.UpdateBatch;
Child.UpdateBatch;

Наборы данных клиентов

Кэширование данных является одной из основных причин TClientDataset Существование и синхронизация отношений мастер / деталь совсем не сложны.

Для этого вы обычно определяете отношение мастер / детализация для двух компонентов набора данных (в вашем случае ADOQuery или же ADOTable). Затем создайте одного поставщика и подключите его к основному набору данных. Подключите один TClientDataset к поставщику, и все готово. TClientDatset интерпретирует подробный набор данных как вложенное поле набора данных, к которому можно получить доступ и связать его с элементами управления с поддержкой данных, как и с любым другим набором данных.

Как только это на месте, вы просто позвоните TClientDataset.ApplyUpdates и клиентский набор данных позаботится о правильном заказе обновлений для основных / подробных данных.

ORMs

Многое можно сказать об ОРМ. Слишком много, чтобы вписаться в ответ по Stackru, поэтому я постараюсь быть кратким.

В последнее время ОРМ получил плохой рэп. Некоторые ученые зашли так далеко, что назвали их анти-паттернами. Лично я думаю, что это немного несправедливо. Объектно-реляционное отображение - невероятно сложная задача, которую нужно правильно решить. ORM пытаются помочь, абстрагируясь от сложности переноса данных между реляционной таблицей и экземпляром объекта. Но, как и все остальное в разработке программного обеспечения, серебряных пуль нет, и ORM не являются исключением.

Для простого приложения ввода данных без большого количества бизнес-правил ORM, вероятно, излишне. Но поскольку приложение становится все более и более сложным, ORM начинает выглядеть более привлекательным.

В большинстве случаев вы захотите использовать сторонний ORM, а не свой собственный. Написание пользовательского ORM, который идеально соответствует вашим требованиям, звучит как хорошая идея, и его легко начать с простых сопоставлений, но вскоре вы начнете сталкиваться с такими проблемами, как отношения родитель / потомок, наследование, кэширование и аннулирование кэша (поверьте мне, я знаю это из опыта). Сторонние ORM уже сталкивались с этими проблемами и потратили огромное количество ресурсов на их решение.

Со многими ORM вы обмениваете сложность кода на сложность конфигурации. Большинство из них активно работают над сокращением базовой конфигурации, обращаясь к соглашениям и политикам. Если вы назовете все свои первичные ключи Id вместо того, чтобы сопоставить каждую таблицу Id столбец к соответствующему Id Свойство для каждого класса вы просто сообщаете ORM об этом соглашении, и оно предполагает, что все таблицы и классы, о которых он осведомлен, следуют соглашению. Вам нужно только переопределить соглашение для конкретных случаев, когда оно не применяется. Я не знаком со всеми ORM для Delphi, поэтому я не могу сказать, кто поддерживает это, а кто нет.

В любом случае вы захотите спроектировать архитектуру своего приложения, чтобы вы могли отталкиваться от решения, какую платформу ORM (или, в этом отношении, любую платформу) использовать как можно дольше.

Другие вопросы по тегам