Как долго закладка TDataset остается действительной?

У меня есть код, показанный ниже, в проекте, над которым я работаю.

procedure TForm.EditBtnClick(Sender:TObject);
begin
  // Mark is form variable. It's private
  Mark = cdsMain.GetBookmark;
  // blabalbal
  .
  .   
  .
end;

procedure TForm.OkBtnClick(Sender:TObject);
var  
  mistakes: Integer;
begin
  //Validation stuff and transaction control
  //removed to not clutter the code
  If cdsMain.ChangeCount <> 0 then 
    mistakes := cdsMain.AppyUpdates(-1); 
  cdsMain.Refresh;
  try
    cdsMain.GotoBookmark(Mark);
    // Yes, I know I would have to call FreeBookmark
    // but I'm just reproducing 
  except
    cdsMain.First;
  end;
end;

Лично я не часто использую закладки - за исключением изменения положения набора данных, где я только перемещал позицию курсора (для создания листинга, заполнения списка строк и т. Д.). Если я Refresh, обновляю (особенно когда фильтр может сделать запись невидимой), повторно загружаю (_3 _ / _ 4_) или любую операцию, которая изменяет данные в наборе данных, я не использую закладки. Я предпочитаю Locate на первичном ключе (используя, конечно, TClientDataset) или повторно изменять параметры.

До каких пор закладка действительна? До Refresh? Пока не будет сделано _8 _ / _ 9_ для повторной выборки данных? Где заканчивается безопасная зона?

Учтите, что в ответе я использую TClientDataset с TSQLQuery (DbExpress).


person Fabricio Araujo    schedule 11.05.2009    source источник


Ответы (3)


Как и c0rwin, так и skamradt уже упоминалось: поведение закладки зависит от используемого вами потомка TDataSet.

Как правило, закладки становятся недействительными во время:

  1. закрыть / открыть
  2. обновить (в наборах данных, которые его поддерживают)
  3. изменения данных (иногда только удаления)

Я знаю, что 1. и 2. могут сделать ваши закладки в TClientDataSets недействительными. Я почти уверен, что для TClientDataSets не имеет значения, какой базовый поставщик используется (TSQLQuery, TIBQuery и т. Д.).

Единственный способ убедиться, что работает, а что нет, - это протестировать. Это означает, что вы совершенно правы, что не используете их: закладки имеют естественный шанс быть ненадежными.

На всякий случай всегда звоните BookmarkValid перед переходом к закладке.

person Jeroen Wiert Pluimers    schedule 11.05.2009
comment
После некоторых экспериментов даже BookmarkValid оказывается ненадежным. Это происходит, когда у вас активирован фильтр для набора данных - он возвращает истину, даже если запись не соответствует условию фильтра. Конечным результатом является выброс исключения. - person Fabricio Araujo; 13.05.2009

Лично я редко использую закладки. Вместо этого я использую идентификатор просматриваемой записи и определяю ее местонахождение после завершения обновления. Если мне нужно перебрать все записи в наборе, я делаю это, используя клон tClientDataset (который получает собственный курсор).

Насколько я понимаю, реализация закладки зависит от поставщика потомка tDataset и может варьироваться в зависимости от реализации. В моем очень простом наборе данных (tBinData) я реализовал закладки в качестве номера физической записи, чтобы он сохраняться между обновлениями, пока запись не была удалена. Я не могу сказать, что это правда для всех реализаций.

person skamradt    schedule 11.05.2009

TDataSet реализует методы виртуальных закладок. Хотя эти методы гарантируют, что любой объект набора данных, производный от TDataSet, возвращает значение, если вызывается метод закладки, возвращаемые значения являются просто значениями по умолчанию, которые не отслеживают текущее местоположение. Потомки TDataSet, такие как TBDEDataSet, повторно реализуют методы закладок для возврата значимых значений, как описано в следующем списке:

  • BookmarkValid, чтобы определить, используется ли указанная закладка.
  • Сравнить закладки, чтобы проверить две закладки на совпадение.
  • GetBookmark, чтобы выделить закладку для вашего текущего положения в наборе данных.
  • GotoBookmark, чтобы вернуться к закладке, ранее созданной GetBookmark.
  • FreeBookmark, чтобы освободить закладку, ранее размещенную GetBookmark.

Получите его здесь

person Artem Barger    schedule 11.05.2009
comment
Спасибо. Я перефразирую вопрос, так что. - person Fabricio Araujo; 11.05.2009
comment
К сожалению, я не помню ответа на этот вопрос, так как давно оставил программирование на Delphi. Моя интуиция подсказывает мне, что он должен быть действителен до тех пор, пока DataSet не будет открыт, но я мог подумать о реализации, где он мог бы быть полезен даже после его открытия / закрытия. Я также склонен согласиться с нижеследующим ответом, поскольку он определенно может зависеть от поставщика. - person Artem Barger; 12.05.2009