Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обновление TClientDataSet


Eugene_e ©   (2003-06-20 14:43:00) 

Добрый день!
Исходные данные:
- Есть клиент TClientDataSet, получающий данные с использованием RemoteServer

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

С уважением, Евгений


Eugene_e   (2003-06-21 15:29:00) [1]

Всем спасибо за отклики.

В результате выяснилось что проблема решается следующим образом:

a) для TDataSetProvider устанавливаем опции [poAutoRefresh,poPropogateChanges]
б) TDataSetProvider.ResolveToDataSet установлен [True]
в) Обработчик TDataSetProvider.AfterUpdateRecord() формируется наподобие следующего:


procedure TSCSRVXD.ds_wpAfterUpdateRecord(Sender: TObject;
SourceDS: TDataSet; DeltaDS: TCustomClientDataSet;
UpdateKind: TUpdateKind);
var
fld: TField;
begin
try
fld := DeltaDS.FieldByName("ID");
except
//По желанию чего-нибудь
end;

fld.ReadOnly := False; //Если был установлен

try
fld.NewValue := SourceDS.FieldByName("ID").AsVariant;
except
//По желанию чего-нибудь
end;

fld := nil;

end;


Таким образом после выполнения на клиенте TClientDataSet.ApplyUpdates(), позиция сразу будет содержать значение автоинкрементного поля.

Евгений
PS. Проверено: D6, MSSQL7


Eugene_e   (2003-06-21 12:25:00) [2]

Манипуляции с DeltaDS можно производить в DatasetProvider.AfterUpdateRecord(), однако внесение изменений в DeltaDS не проходит, хотя после обновления мастер-записи значение автоинкрементного поля уже доступно через SourceDS.FieldByName("ID").AsInteger


Polevi   (2003-06-21 10:01:00) [3]

>Eugene_e © (20.06.03 15:07)
все правильно, только
>а затем вернув это значение в DatasetProvider.AfterApplyUpdates()

не нужно, надо так

DeltaDS.FieldByName("ID").NewValue:=@@IDENTITY


AkaSaint   (2003-06-21 00:10:00) [4]

У меня такая же ситуация, я после ApplyUpdates делаю в клиентском НД Locate по всем полям, кроме автоинкрементного. Но тут такой недостаток, что если все остальные поля, кроме автоинкрементного, могут составить неуникальное значение, то будет ай-ай-ай.


Eugene_e   (2003-06-20 17:50:00) [5]

Как раз в локальный кэш я и могу добавить запись без значения ключевого поля (того, что ключевое по базе) и даже сохранить ее на сервере без всякой обработки в BeforeUpdateRecord(), но вот получить обратно значение автоинкрементного поля проблемно :)


Juggler   (2003-06-20 16:44:00) [6]

Как это ты не знаеш значение ключевого поля?
Ограничения на поля не дадут просто внести запись в локальный кэш.
если нет значения ключевого поля.
Геморой в MIDAS с автоинкрементальными полями.
Еще до ApplyUpdates добраться надо.;)


Eugene_e   (2003-06-20 15:07:00) [7]

А чем сей метод может быть мне полезен?
Хотелось бы понять могу я сделать это без излишних манипуляций? Теоретически я понимаю, что используя DatasetProvider.BeforeUpdateRecord() я могу заменить процедуру добавления записи убрав данную запись из DeltaDS, получив код добавленной записи через тот же @@Identity (MSSQL), а затем вернув это значение в DatasetProvider.AfterApplyUpdates(), но как-то громоздко выглядит.
Может у кого-нибудь еще есть предложения?


Polevi   (2003-06-20 14:49:00) [8]

см DatasetProvider.BeforeUpdateRecord


Наверх

Титульная страница Поиск, карта сайта Написать письмо