2009-05-11 3 views
9

У меня есть код, как показано ниже в проекте, в котором я работаю.Как долго заставка 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; 

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

До тех пор, пока не будет включена закладка? До Refresh? Пока не будет выполнен Close/Open для получения данных? Где заканчивается безопасная зона?

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

ответ

5

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

В общем, закладки становятся недействительными в:

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

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

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

Чтобы быть в безопасности, всегда звоните в закладку BookmarkValid перед тем, как перейти к закладке.

+5

После некоторых экспериментов даже BookmarkValid оказывается ненадежным. Это происходит, когда у вас есть фильтр, активированный в наборе данных - он возвращает true, даже если запись не соответствует условию фильтра. Конечным результатом является выброс исключения. –

1

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

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

Получить его из here

+0

спасибо. Поэтому я перефразирую вопрос. –

+0

К сожалению, я не помню ответа на этот вопрос, так как я давно оставил Delphi. Моя интуиция говорит мне, что она должна быть действительной до тех пор, пока DataSet не будет открыт, но я мог бы подумать о реализации, где это может быть полезно даже после открытия/закрытия. Я также согласен с ответом ниже, поскольку это определенно может зависеть от поставщика. –

4

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

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