2009-05-11 17 views
9

Ho un codice come sotto in un progetto che sto lavorando.Quanto tempo rimane valido un segnalibro 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; 

Personalmente, io non uso i segnalibri molto - se non per riposizionare un insieme di dati in cui mi sono trasferito solo la posizione del cursore (per creare un profilo, riempire una lista di stringhe, ecc). Se I Refresh, aggiornamento (specialmente quando un filtro può rendere invisibile il record), refetch (Close/Open) o qualsiasi operazione che modifica i dati nel set di dati, non utilizzo i segnalibri. Preferisco Locate sulla chiave primaria (utilizzando un TClientDataset, ovviamente) o la richiesta di modifica dei parametri.

Fino a quando è valido un segnalibro? Fino a un Refresh? Fino a quando non viene effettuato il Close/Open per il recupero dei dati? Dove finisce la zona sicura?

Prendere in considerazione nella risposta Sto usando TClientDataset con un TSQLQuery (DbExpress).

risposta

5

come sia c0rwin e skamradt già menzionano: il comportamento segnalibro dipende dal discendente TDataSet si utilizza.

In generale, i segnalibri diventano non valido durante:

  1. chiusura/apertura
  2. aggiornamento (su insiemi di dati che lo supportano)
  3. modifiche dei dati (a volte solo delezioni)

che conosco 1. e 2. possono invalidare i segnalibri in TClientDataSets. Sono quasi sicuro che per TClientDataSets non importa quale provider sottostante è utilizzato (TSQLQuery, TIBQuery, ecc.).

L'unico modo per assicurarsi che cosa funziona e cosa no lo sta testando. Ciò significa che hai completamente ragione nel non usarli: i segnalibri hanno una intrinseca possibilità di essere inaffidabili.

Per sicurezza, chiamare sempre BookmarkValid prima di accedere a un segnalibro.

+5

Dopo alcune sperimentazioni, anche BookmarkValid si dimostra inaffidabile. Succede quando si attiva un filtro sul set di dati - restituisce true anche se il record non corrisponde alla condizione del filtro. Il risultato finale è il lancio di un'eccezione. –

1

TDataSet implementa metodi di bookmark virtuali. Sebbene questi metodi garantiscano che qualsiasi oggetto dataset derivato da TDataSet restituisca un valore se viene chiamato un metodo di segnalibro, i valori di ritorno sono semplicemente valori predefiniti che non tengono traccia della posizione corrente. Discendenti di TDataSet, come TBDEDataSet, implementare di nuovo i metodi segnalibro per restituire valori significativi come descritto nel seguente elenco:

  • BookmarkValid, per determinare se un segnalibro specificato è in uso.
  • CompareBookmarks, per testare due segnalibri per vedere se essi sono uguali.
  • GetBookmark, di destinare un segnalibro per la posizione corrente nel set di dati.
  • GotoBookmark, per tornare a un segnalibro creato in precedenza da GetBookmark
  • FreeBookmark, per liberare un segnalibro precedentemente allocata da GetBookmark.

garantita da here

+0

Grazie. Riformero la domanda, quindi. –

+0

Purtroppo non ricordo di aver risposto a questa domanda, da quando ho lasciato Delphi in programmazione molto tempo fa. La mia intuizione mi dice che dovrebbe essere valida fino all'apertura di DataSet, ma potrei pensare all'implementazione dove potrebbe essere utile anche dopo l'apertura/chiusura. Tendo anche a concordare con la risposta sotto, dato che potrebbe sicuramente dipendere dal venditore. –

4

Personalmente io uso raramente i segnalibri. Io invece uso l'id del record che sto visualizzando ed eseguo un locate su di esso una volta che l'aggiornamento è completo. Se ho bisogno di scorrere tutti i record del set, lo faccio usando un clone del tClientDataset (che ottiene il suo cursore).

E 'la mia comprensione è che l'attuazione del segnalibro spetta al fornitore del discendente TDataSet e può variare tra le implementazioni. Nel mio set di dati molto semplice (tBinData), ho implementato i segnalibri come numero di record fisico in modo tale che rimarrebbe tra gli aggiornamenti finché il record non è stato cancellato. Non posso parlare così per tutte le implementazioni.

Problemi correlati