Форум: "Базы";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];
ВнизОдин DataSet - два курсора Найти похожие ветки
← →
-=GUEST=- (2003-10-21 17:27) [0]Давно мучает одна проблема.
Допустим есть грид, подключенный к DataSet"у.
На этой же форме есть DBLookupComboBox, который ведет выборку по аналогичному Dataset"у.
Приходится создавать два одинаковых DataSet(Выполнять один и тот же запрос дважды)
Есть ли возможность сделать один Dataset, а навигация по нему осуществляется разными курсорами - независимо в Гриде и LookupComboBox
← →
TP (2003-10-21 17:31) [1]Нет
← →
Vlad (2003-10-21 17:33) [2]Можно.
Используй TClientDataSet
← →
-=GUEST=- (2003-10-21 17:37) [3]По поводу TClientDataset - поподробнее, plz.
← →
Vlad (2003-10-21 17:45) [4]А чего тут подробнее то ?
У тебя задача, не делать дважды один и тот же запрос к серверу.
Так делай его один раз. Результат из Query помещаешь в ClientDataSet, и имеешь два независимых но одинаковых набора данных.
← →
-=GUEST=- (2003-10-21 17:51) [5]Имеется в виду Midas.
Если не сложно пример или ссылку(идея понятна, кроме "Результат из Query помещаешь в ClientDataSet" - не работал еще с ClientDataSet)
Заранее благодарен.
← →
TP (2003-10-21 17:54) [6]Что в лоб, что полбу:
TQuery и TClientDateSet потомки TDataSet,а как извесно 1+1=2.
← →
-=GUEST=- (2003-10-21 17:59) [7]При чем тут кто кого потомки?
Если кому-то будет интересно,
пример в Delphi\Demos\Midas\Aggregate
← →
Vlad (2003-10-21 18:00) [8]-=GUEST=- (21.10.03 17:51) [5]
Лень справку открыть ?
>TP (21.10.03 17:54) [6]
Причем тут это ?
← →
-=GUEST=- (2003-10-21 18:09) [9]"Лень - это способ отдыхать заранее.", она же двигатель прогресса.
Остался совсем простой вопрос - закачиваюся данные в ClientDataSet по-необходимости или все сразу.
← →
MsGuns (2003-10-21 18:10) [10]Для парадокса лучший выход в данной ситуации - Vlad © (21.10.03 17:33) [2] - не создаются доп. файлы типа _sqxxxx плюс много чего хорошего у CDS. Если кол-во записей справочника небольшое, то я вообще бы отказался от DBLookUpComboBox, заменив его на модальную форму с гридом, отображающим этот CDS. Плюсов море - начиная с того, что видно все поля таблицы и заканчивая тем, что можно делать любые поиски, фильтры, правки "на лету" и т.д., т.е. имеем богатый ноабор методов полнофункционального датасета вместа кастрированного лукапкомбобокса.
← →
Vlad (2003-10-21 18:19) [11]MsGuns © (21.10.03 18:10) [10]
вместа кастрированного лукапкомбобокса
:)))
Ну уж эт ты загнул.
Многофункциональные компоненты тоже имеют свои минусы :)
← →
-=GUEST=- (2003-10-21 18:37) [12]Может я что-то не правильно делаю, но происходит следующее.
Лежит Query+DataSource+Grid
и Provider+ClientDataSet+DataSource+Grid
Если делаю ClientDataSet.Active := True
Открывается и то и другое, и курсок одинаковый - при переходе в одном гриде в другом тоже перемещаюсь.
Если сделать Query.Active := True, а потом ClientDataSet.Active := True, то Query самопроизвольно закрывается, но после повторного открытия работает как надо, два разных курсора - но и запрос открывается дважды.
Если есть кто добрый, рабочий пример - шо к чему.
← →
-=GUEST=- (2003-10-21 18:44) [13]Такое впечатление, что ClientDataSet при своем открытии открывает Query, скачивает из него все данные(видно по подключенному к Query гриду), а потом закрывает его.
Не совсем то чего хотелось бы.
← →
MsGuns (2003-10-21 20:21) [14]>Vlad © (21.10.03 18:19) [11]
>Ну уж эт ты загнул.
Ничего я не загнул. Так и есть.
>Многофункциональные компоненты тоже имеют свои минусы :)
Конечно, вертолетом сложнее управлять чем самокатом.
← →
AlexGreG (2003-10-22 08:42) [15]А мне про лень понравилась шутка :)))
← →
TP (2003-10-22 09:05) [16]> -=GUEST=- (21.10.03 18:37) [12]
Не очень понятно, что происходит.
Я клонирую TDataSet так:
function GetData(ADataSet: TDataSet): OleVariant;
begin
with TDatasetProvider.Create(nil) do
try
Dataset:= ADataset;
Result:= Data;
finally
Free;
end;
end;
procedure TForm1.Button1Click(Sender:TObject);
begin ClientDataset1.Data;= GetData(ADODataset1); end;
Конечно к этому времени ADODataset.Active:= True
После этого ADODataset можешь Close, можешь Free. По барабану.
Получена копия, с которой можешь делать, что хочешь.
← →
-=GUEST=- (2003-10-22 10:52) [17]>TP (22.10.03 09:05) [16]
Спасибо, работает.
Единственный недостаток - ClientDataSet фэтчик все данные из DataSet"a, а не загружает по необходимости. На больших запросах, наверное, лучше все таки изпользовать два аналогичных Query.
← →
TP (2003-10-22 11:12) [18]Это не недостаток. Это принцип работа TDataSet.
Нет запроса нет данных.
Что бы в TClienDataset обновились данные, необходимо закрыть
TDataset, снова открыть и повторить клонирование.
Можно обойтись и без TClienDataset.
Например так:
function TDM.Clone(DS: TADODataSet): TADODataSet;
begin
if not DS.Active then DS.Open;
Result:= TADODataSet.Create(Self);
with Result do begin
CommandText:= DS.CommandText;
Connection:= DS.Connection;
Parameters.Assign(DS.Parameters);
Open;
end;
end;
А лучше не заниматься ерундой. Измени логику программы, что бы
не было проблемы "Один DataSet - два курсора"
← →
Nikolay M. (2003-10-22 11:23) [19]Да брось тогда ты этот DBLCB. Возьми простой DBComboBox и заполни его Items-ы руками - просто и сурово :)
← →
-=GUEST=- (2003-10-22 12:05) [20]>Nikolay M. © (22.10.03 11:23) [19]
В идеале должно было бы:
1. Загрузка позиций по запросу, а не все сразу (допустим там пару тыся записей с картинками)
2. Раздельная навигация.
ClientDataSet - не решает первого. Т.е. качает все сразу.
>TP (22.10.03 11:12) [18]
... не заниматься ерундой. Измени логику программы ...
Есть множество задач в кот. удобно иметь два одинаковых DataSet"a
И удобно не с точки зрения программиста, а для работы пользователя - к удобству которого в конечном итоге и стоит стремится.
Решение проблемы на мой взгляд выглядит так.
Есть какой-то объект, допустим "TSuperQuery" - осущ. непосредстненную работу с базой данных.
К нему подключ. "TSuperDataSet"+DataSource+TDBGrid(или любой виз. комп.).
TSuperDataSet - осуществляет навигацию по TSuperQuery и имеет свой курсор. Если для TSuperDataSet нужны данные, кот. нет в TQuery - он их фэтчит, причем если эти же данные запросит другой TSuperDataSet - повторного фэтча не будет.
Такой херни наверно нету.
← →
-=GUEST=- (2003-10-22 12:13) [21]В ClientDataSet есть ф-ция CloneCursor, кот. позволяет шарить одни данные между двумя(и более) ClientDataSet. Если еще решить проблему с фэтчем по запросу.
Опять таки в ClientDataSet есть с-во FetchOnDemand - но оно желаемого результата не дает.
← →
TP (2003-10-22 12:23) [22]Метод CloneCursor TClientDataSet не создаёт второй курсор.
Он создаёт копию "родителя".(см. исходники).
Полбзователей конечно надо уважать, но зачем нужен TSuperDataSet,
я так и не понял.
← →
-=GUEST=- (2003-10-22 12:41) [23]Может по исходникам и так, но в хелпе:
Call CloneCursor to share the data belonging to another client dataset.
Последняя проблема - возможно ли заставить ClientDataSet загружать данные по надобности
>TP (22.10.03 12:23) [22] но зачем нужен TSuperDataSet
Ну это для примера.
Можно сказать что TSuperQuery = TDataSetProvider, а TSuperDataSet = TClientDataSet
Но чтобы Sharing Data - а не создание копии(а Вы говорите это происходит по исходникам), и Fetch-On-Demand для этого самого Shared Data.
← →
TP (2003-10-22 13:29) [24]У TDataSetProvider.Option есть значение poAutoRefres.
В D5 это неработает однозначно, в D6,7 не знаю, ещё не пробовал.
Так что проблему автоматического обновления запроса я решал при помощи COM-ика с событием, которое при изменении данных на сервере срабатывало у клиентов.
Но это всё делалось при помощи MIDAS.
← →
Nikolay M. (2003-10-22 13:52) [25]
> -=GUEST=- (22.10.03 12:05) [20]
> >Nikolay M. © (22.10.03 11:23) [19]
> В идеале должно было бы:
> 1. Загрузка позиций по запросу, а не все сразу (допустим
> там пару тыся записей с картинками)
> 2. Раздельная навигация.
А как по-твоему, в DBLCB тогда появятся ВСЕ записи, если не фетчить их все? Сделай тогда вспомогательный запрос, в котором будет селект одного нужного поля и пихай его в DB(Lookup)ComboBox.
← →
-=GUEST=- (2003-10-22 14:13) [26]>Nikolay M. © (22.10.03 13:52) [25]
По поводу DBLookupComboBox утверждать не буду, но вот грид загружает записи по необходимости, да и LookupComboBox должен делать точно также. А то выходит ты раскрываешь его и тут фэтчится в примеру 400 000 записей - не логично как-то.
Вспомогательный запрос я постоянно и использую. Но как написано в теме топика - "Давно мучает одна проблема" - зачем выполнять два разных запроса, загружать одну и туже информацию (даже если фетчатся только необходимые записи - выходит ~трафик*2, а если будет Paradox то и поболее) если можно найти способ "клонирования" курсора. ClientDataSet практически решает эту проблему.
← →
TP (2003-10-22 14:18) [27]TDBGrid ни когда не загружал записи. Во все времена записи грузились в TDataSet и его потомков. TDBGrid только отображает записи из TDataSet.По крайней мере так было до сегодняшнего дня.
← →
Nikolay M. (2003-10-22 14:26) [28]
> грид загружает записи по необходимости
Данные загружает DataSet, плюс фетчить все или по частям - зависит от используемых компонент.
А то, что есть необходимость фетчить 400 000 записей - неправильно идеологически. Ты что, хочешь довести до инфаркта юзера, предложив ему список в почти поллимона записей?
← →
-=GUEST=- (2003-10-22 14:39) [29]>TP (22.10.03 14:18) [27]
Мы же не в детском саду. Если Вы подключите TDBGrid к TQuery, то он будет грузить столько записей, сколько потребует TDBGrid для отображения. Т.е. если опустить детали грузит записи все-таки грид, точнее "требует" их у набора данных
А по поводу кто кого потомок Вы объясняли еще в начале топика.
ПРОБЛЕМА заставить ClientDataSet загружать записи по запросу от грида. Или какое-то подобное решение.
← →
TP (2003-10-22 14:49) [30]Похоже мы в детском саду: TQuery грузит столько записей, сколько записей в базе удолетворяет условиям запроса. А TDBGrid отображает столько записей, сколько записей уместится в высоте TDBGrid.
← →
Vlad (2003-10-22 14:51) [31]>TP (22.10.03 14:49) [30]
TQuery грузит столько записей сколько настроено в БДЕ алиасе или столько сколько отфетчит юзер.
← →
-=GUEST=- (2003-10-22 15:08) [32]В любой умной книжке описана разница между TQuery и TTable и все её знают.
Не важно как грузит TQuery(TQuery для примера взято - что бы указать что используется не TTable, для IB вообще FIBPLus используется - тут будет меньше споров кто как фетчит ).
Это детали. В другом проблема.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.035 c