Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.11.13;
Скачать: CL | DM;

Вниз

Один 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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.049 c
4-42277
samson
2003-09-12 10:54
2003.11.13
сообщение в момент выполнения запроса


3-40935
zsr
2003-10-17 13:27
2003.11.13
BatchMove для ADOQuery


14-41914
Nick-From
2003-10-14 15:53
2003.11.13
Нужен радио телефон


1-41295
Liavik
2003-10-31 13:21
2003.11.13
DateTimePicker


1-41156
Михаил
2003-11-03 11:59
2003.11.13
Help