Есть ли способ в Delphi кэшировать строки master-detail и публиковать как основные, так и дочерние строки одновременно
Я хочу опубликовать в памяти некоторые дочерние строки, а затем условно опубликовать их или не публиковать их в базовой базе данных SQL, в зависимости от того, опубликована или не опубликована родительская строка. Мне не нужен полный ORM, но, может быть, только это:
- пользователь нажимает кнопку Добавить врача. Откроется диалоговое окно добавить врача.
- прежде чем нажать Ok на Add doctor, в диалоговом окне Add doctor пользователь добавляет одного или нескольких пациентов, которые сохраняются только в памяти.
- пользователь нажмите Ok в окне Добавить врача. Теперь все пациенты хранятся, плюс новый врач.
- если пользователь нажал кнопку Отмена в окне врача, вся информация о докторе и пациенте отбрасывается.
попробуйте, если хотите, мысленно представить, как вы могли бы сделать это, используя Delphi data aware controls и tadoquery или другие объекты ADO. Если есть не-ADO-конкретный способ сделать это, меня это тоже интересует, я просто бросаю ADO, потому что я использую MS-SQL Сервер и ADO в моих текущих приложениях.
Итак, у предыдущих работодателей, где я работал в течение короткого времени, у них был класс под названием TMasterDetail
Это было специально написано, чтобы добавить выше в наборы записей ADO. Иногда это срабатывало, а иногда это не удавалось в некоторых действительно интересных и трудных для исправления способах.
есть ли что-нибудь встроенное в VCL или любой сторонний компонент, который имеет надежный способ выполнения этой техники? Если нет, это то, о чем я говорю выше требуя ОРМ? Я думал, что ORMs считались "плохими" многими людьми, но выше приведен довольно естественный шаблон пользовательского интерфейса, который может возникнуть в миллионах приложений. Если бы я использовал не-ADO не-Delphi-db-dataset стиль работы, вышеизложенное не было бы проблемой практически в любом слое персистентности, который я мог бы написать, и все же, когда базы данных с первичными ключами, которые используют значения идентификаторов для связи основных и подробных строк, попадают в картину, все усложняется.
обновление: В данном случае сделки вряд ли идеальны. (Фиксация / откат-слишком грубый механизм для моих целей.)
1 ответов
вы задаете два отдельных вопроса:
- как кэшировать обновления?
- как я могу одновременно фиксировать обновления связанных таблиц.
кэшированные обновления могут быть выполнены несколькими различными способами. Какой из них лучше зависит от конкретной ситуации:
обновления пакета ADO
поскольку вы уже заявили, что используете ADO для доступа к данным, это разумный вариант. Вам просто нужно Установите тип LockType в ltBatchOptimistic и CursorType либо ctKeySet или ctStatic перед открытием набора данных. Затем вызовите TADOCustomDataset.UpdateBatch, когда вы будете готовы к фиксации.
Примечание: базовый поставщик OLEDB должен поддерживать пакетные обновления, чтобы воспользоваться этим. Поставщик SQL Server полностью поддерживает это.
Я не знаю другого способа обеспечить связь master / detail при сохранении данные, чем вызывать UpdateBatch последовательно для обоих наборов данных.
Parent.UpdateBatch;
Child.UpdateBatch;
Клиентские Наборы Данных
кэширование данных является одной из основных причин TClientDataset
существование и синхронизация отношения master / detail совсем не сложно.
для этого вы определяете отношение master / detail для двух компонентов набора данных как обычно (в вашем случае ADOQuery
или ADOTable
). Затем создайте один провайдер, и подключить его к мастер dataset. Подключить один TClientDataset
к провайдеру, и вы закончили. TClientDatset
интерпретирует набор данных detail как вложенное поле набора данных, к которому можно получить доступ и привязать элементы управления data aware, как и к любому другому набору данных.
как только это будет на месте, вы просто позвоните TClientDataset.ApplyUpdates
и набор данных клиента позаботится о заказе обновлений для основных / подробных данных правильно.
ORMs
там много что может быть сказал об Ормах. Слишком много, чтобы поместиться в ответ на StackOverflow, поэтому я постараюсь быть кратким.
Ормы получили плохой рэп в последнее время. Некоторые ученые зашли так далеко, что назвали их анти-паттернами. Лично я считаю, что это немного несправедливо. Объектно-реляционное отображение-невероятно сложная проблема для правильного решения. ORMs пытается помочь, абстрагируясь от большой сложности, связанной с передачей данных между реляционной таблицей и экземпляром объекта. Но как с все остальное в разработке программного обеспечения нет серебряных пуль и платформы не исключение.
для простого приложения ввода данных без большого количества бизнес-правил ORM, вероятно, перебор. Но по мере того, как приложение становится все более и более сложным, ORM начинает выглядеть более привлекательным.
в большинстве случаев вы захотите использовать сторонний ORM, а не сворачивать свой собственный. Написание пользовательских ОРМ, который идеально соответствует вашим требованиям, звучит как хорошая идея, и ее легко чтобы начать работу с простыми сопоставлениями, но вы скоро начнете сталкиваться с такими проблемами, как отношения родителя/ребенка, наследование, кэширование и недействительность кэша (поверьте мне, я знаю это по опыту). Сторонние ORMs уже столкнулись с этими проблемами и потратили огромное количество ресурсов на их решение.
со многими ORMs вы торгуете сложностью кода для сложности конфигурации. Большинство из них активно работают над уменьшением конфигурации шаблона, обращаясь к соглашениям и политики. Если вы назовете все свои первичные ключи Id
вместо того, чтобы сопоставлять соответствующего Id
свойство для каждого класса вы просто говорите ORM об этом соглашении, и он предполагает, что все таблицы и классы его знают о соблюдении соглашения. Вам нужно только переопределить Соглашение для конкретных случаев, когда оно не применяется. Я не знаком со всеми Ормами для Delphi, поэтому я не могу сказать, какие поддерживают это, а какие нет.
в любом случае вы захотите создать свою архитектуру приложения, чтобы вы могли отталкивать решение о том, какую структуру ORM (или, если на то пошло, любую структуру) использовать как можно дольше.