Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];

Вниз

Проблема при организации MDI+MIDAS.   Найти похожие ветки 

 
pulp   (2004-04-30 06:07) [0]

Доброго времени суток уважаемые мастера.

Возникла проблема следующего характера:
Каким образом с помощью одного подключения (напр. TSocketConnection) нескольким наборам данных (TClientDataSet) получать доступ к одному и тому же провайдеру (TDataSetProvider) на сервере. При этом использовать разные SQL-запросы и т.д., т.е. чтобы работа ничем не отличалась, когда у нас ClientDataset"ы cвязаны с разными провайдерами, которые на сервере получают доступ к одной и той же таблице.

Пояснение:
Это необходимо при реализации БД в MDI-приложении. Т.е. мы можем
открыть несколько экземпляров одной и той же формы, на которой
расположен ClientDataset (т.е. несколько ClientDataset получают доступ к одному и тому же провайдеру (TDatasetProvider)). На разных экземплярах формы делать разные выборки, редактировать данные и т.п.

Пример ошибки:
1. Пусть мы открыли два экземпляра одной формы;
2. На первой форме сделали следующую выборку (SELECT * FROM T WHERE Key<1000);
3. На второй форме сделали следующую выборку (SELECT * FROM T WHERE Key>1000);
4. Теперь, если мы на первой форме обновим данные (CleintDataSet.Refresh), то отобразятся данные второго запроса (Key>1000);

При реализации MDI на файл-серверной (двухзвенка) технологии проблем никаких. Т.е. при создании нового набора данных (напр. TTable) мы получаем "свой" независисый доступ к БД.

Дополнение:
Если мы открыли два набора данных с разными (взаимоисключающими
запросами) связанных с одним провайдером, то на форме, которая была открыта ранее возникают также следующие ошибки:
- RefreshRecord (вызывает исключительную ситуацию: "Запись не
 найдена");
- Метод ApplyUpdate не сохраняет данные, т.к. не находит их (талица на   сервере содержит данные запроса набора данных, который был открыт   позднее);
- При таком раскладе становится невозможно применения свойства
 PacketRecord отличного от -1;
- Возможно ещё что-нибудь (много чего)...

Также, при открытии второго и более набора данных, связанного с одним провайдером возникает ошибка "Таблица (на сервере) уже открыта", т.е. при отктытом наборе данных на сервере мы не можем изменять свойство SQL.

В общем вопрос можно перефразировать: как сделать, чтобы при каждом новом подключении к одному и тому же провайдеру на сервере создавалась отдельная (независимая) копия набра данных (используя одно подключение)?

Буду рад любому отклику!


 
sniknik ©   (2004-04-30 08:20) [1]

сомнения у меня вызывает правильность такой организации... но тем не менее

возможно получится, держать всетаки одну связку TDataSetProvider - TClientDataSet (считаем этот датасет главным) гденибудь датамодуле, а в mdi   формах использовать клонированные от него клиентдатасеты (ClientDataSet.CloneCursor), несмотря на название данные он не клонирует а разделяет клонируется сам компонент, так что выборка будет не совсем независимая, не так как нужно... но попробовать можно.


 
pulp   (2004-04-30 08:34) [2]

Да, это конечно тоже решение. Только вот на сервере 100 таблиц, на клиенте 100 "лишних" ClientDataSet"ов, какой-то не очень "тонкий" клиент получается.
По поводу Ваших сомнений: будур рад выслушать Ваши рекомендации по организации MDI приложений в такой связке.

С уважением...


 
sniknik ©   (2004-04-30 08:46) [3]

> Только вот на сервере 100 таблиц, на клиенте 100 "лишних" ClientDataSet"ов, какой-то не очень "тонкий" клиент получается.
наоборот, 100 лишних датасетов-заголовков-курсоров но не данных займут гораздо меньше ресурсов чем хотя бы две небольшие копии данных, как у тебя описано.

> По поводу Ваших сомнений: будур рад выслушать Ваши рекомендации по организации MDI приложений в такой связке.
сомнения чисто теоретические, обосновать мне их трудно ;о), задачи такой у меня не стояло (редактировать одно и тоже с разных форм), наоборот всегда ограничивали если уж открыл справочник то второй не откроеш ... даже если с другой формы ссылка на него то "подымается" уже открытый а не создается новый.
(кстати надо посмотреть как 1С в этом случае делает, и не 7ку которая как файл сервер работает(проше открыть кучу копий) а восьмерку там где на трехзвенте, тоже же должны были думать как лутше, и что сделали?)


 
pulp   (2004-04-30 09:12) [4]

Да, конечно, можно ввести ограничения (что очень не желательно), т.е. сделать как 1С"ке - если форма уже открыта, то при повторной попытке открытия просто активировать её и помещать на передний план.
А тогда как поступить, если разные пункты вызывают одну и туже форму, на которой открываются наборы данных с результатами разных выборок.
Например, в БД есть таблица с полем статус. И в зависимости от пункта меню, мы открываем эту таблицу и делаем выборки по разным статусам. Конечно можно для каждой выборки на сервере бросить по отдельному комоненту набора данных и провайдера, а если этих статусов порядка 300?
Короче это всё вода. Проблема решается, если на каждую форму кидать компонент подключения к удалённому провайдеру (напр. TSocketConnection). Тогда для каждой формы на сервере создаётся отдельный экземпляр наборов данных. Но это ведь так "НЕКРАСИВО" и достаточно ресурсоёмко (моё, пока непроверенное, предположение). Да к тому же там возникают новые проблемы с ограничением доступа и т.п.

С уважением...


 
Polevi ©   (2004-04-30 09:46) [5]

На каждый экземпляр MDI окна - свой экземпляр TDataModule со своей TSocketConnection сессией.
+ возможное кеширование справочных датасетов


 
Nikolay M. ©   (2004-04-30 09:58) [6]

Имхо, такой подход в сабже - неоправданный геморрой на свою пятую точку. Но если надо, значит надо...
Как вариант, можно отказаться от DBAware-компонент, селекты производить каждый раз формируя новый запрос (кстати, что у тебя SELECT-ы забыли на клиенте? какой же он тогда получается тонкий?), а операции вставки/изменения/удаления делать через методы сервера, например: CDS.AppServer.DeleteUser (UserID : integer).
Поднимать ли каждый раз новый коннект, возиться с массивом провайдеров, сделать, как высказался я или что-то еще - выбор за тобой.


 
pulp   (2004-04-30 09:58) [7]

Т.е. как я и писал сделать "НЕКРАСИВО"... ладно...

Для уточнения понимания: можно необходимые компоненты бросить ведь и на само MDI окно и не брать TDataModule, а то уж больно много юнитов получается. Исправьте меня пожалуйста, если я не прав.

> + возможное кеширование справочных датасетов
Можно уточнить, что это значит?


 
Nikolay M. ©   (2004-04-30 10:07) [8]


> > + возможное кеширование справочных датасетов
> Можно уточнить, что это значит?

Справочник-таблица городов у тебя часто меняется? Скорее всего нет, но навигация по нему может происходить из разных MDI-окон. Вывод - таблицу нужно открыть один раз, а потом разделять открытые данные между разными MDI-окнами. Либо CloneCursor попробовать, либо, как я уже написал, вместо, скажем, DBLookupComboBox использовать просто ComboBox.


 
pulp   (2004-04-30 11:08) [9]

> To Nikolay M.

> Как вариант, можно отказаться от DBAware-компонент, селекты
> производить каждый раз формируя новый запрос (кстати, что у
> тебя SELECT-ы забыли на клиенте?)

Юзается свойство CommandText ClientDataSet"а. Для доступа к данным кроме компонентов ClientDataSet ничего не используется.

А с MDI морочусь потому, что программа уже в использовании и юзверги к данному фейсу привыкли. Задача стоит в переводе системы на трехзвенку с минимальными изменениями в функциональноси и фейсе.

А как Вы посоветуете, переводить достаточно большой проект (порядка 100 форм) к одноформенному виду или как? Много ли ещё подводных камней всплывёт на данном пути?

С уважением...


 
Nikolay M. ©   (2004-04-30 12:08) [10]


> Юзается свойство CommandText ClientDataSet"а.

И совершенно напрасно. Теряется смысл многозвенки - общаться могут только соседние слои, а ты ломишься по головам провайдеров напрямую к базе. Изменятся названия полей - будешь всем юзерам клиентскую программу обновлять?


> стоит в переводе системы на трехзвенку с минимальными изменениями
> в функциональноси и фейсе.

А смысл? Будут проблемы, по сути схожие с проблемами перевода однопользовательской системы на многопользовательскую: меняется структура системы, простым Копи-Паст или заменой Alias-ов не обойтись.


> А как Вы посоветуете, переводить достаточно большой проект
> (порядка 100 форм) к одноформенному виду или как? Много
> ли ещё подводных камней всплывёт на данном пути?

Не занимался подобным переводом, но проблем, думаю, будет достаточно. Проще все переписать. "Займет это одну неделю. Да, всего одну, не больше. Зато будет все правильно." :)



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.032 c
14-1083567626
Белый волк
2004-05-03 11:00
2004.05.23
Правильное отображение кирилицы в консольном приложении Delphi


14-1083693907
Шишкин Илья
2004-05-04 22:05
2004.05.23
Проверьте ссылку


3-1083156599
Санёк
2004-04-28 16:49
2004.05.23
Чтение данных с MS SQL блоками


14-1083760405
Daniel
2004-05-05 16:33
2004.05.23
Корректное завершение программы.


3-1083062318
UE
2004-04-27 14:38
2004.05.23
DBExpress -> TSQLConnection -> DBX Error: ...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский