2009-07-08 16 views
5

Im AfterPost-Ereignishandler für ein ClientDataSet benötige ich die Informationen, wenn die Funktion ApplyUpdates für den aktuellen Datensatz eine Aktualisierung oder eine Einfügung durchführt.Wie kann ich feststellen, ob ApplyUpdates Daten einfügt oder aktualisiert?

Das AfterPost-Ereignis wird für neue und aktualisierte Datensätze ausgeführt, und ich möchte keine neue Flag-Variable deklarieren, um anzuzeigen, ob ein 'Update' oder 'Insert' Vorgang ausgeführt wird.

Beispielcode:

procedure TdmMain.QryTestAfterPost(DataSet: TDataSet); 
begin 
    if IsInserting(QryTest) then 
    // ShowMessage('Inserting')... 
    else 
    // ShowMessage('Updating'); 

    QryTest.ApplyUpdates(-1); 
end; 

Die Anwendung wird ein Protokoll in der Afterpost Methode schreiben, nachdem ApplyUpdate abgeschlossen hat. Diese Methode ist also der Ort, der der Aktion am nächsten ist. Ich würde eine Lösung vorziehen, die vollständig in diesen Event-Handler eingefügt werden kann.

Wie kann ich die IsInserting-Funktion mithilfe von Informationen in der ClientDataSet-Instanz QryTest implementieren?

Bearbeiten: Ich werde ClientDataSet.UpdateStatus versuchen, die here erklärt wird.

+0

Was planen Sie zu tun? Validierungen durchführen, Benutzeroberfläche aktualisieren oder Daten manipulieren? – zendar

+0

Die Anwendung schreibt ein Protokoll in die AfterPost-Methode, nachdem ApplyUpdate abgeschlossen wurde. Diese Methode ist also der Ort, der der Aktion am nächsten ist. Ich würde eine Lösung vorziehen, die vollständig in diesen Event-Handler eingefügt werden kann. Das Überprüfen des Delta-Arrays scheint hier der einfachste Weg zu sein. – mjn

+0

Dies ist der beste Ort, wenn Sie sich pro Benutzer auf der Clientseite anmelden. Wenn Sie eine zentrale Protokollierung für alle Benutzer durchführen möchten, ist die Position auf dem Server im AfterApplyUpdates-Ereignis für TDataSetProvider besser. – zendar

Antwort

5

ApplyUpdates gibt Ihnen diese Informationen nicht - da es Einfügen, Aktualisieren und Löschen sein kann.

ApplyUpdates wendet die Änderungsinformationen an, die im Delta-Array gespeichert sind. Diese Änderungsinformation kann beispielsweise eine beliebige Anzahl von Änderungen verschiedener Typen (Einfügungen, Löschungen und Aktualisierungen) enthalten, und alle diese werden auf denselben Aufruf angewendet.

Auf TDatasetProvider haben Sie die BeforeUpdateRecord -Ereignis (oder etwas ähnliches, Schlaf macht lustige Dinge auf Speicher :-)). Dieses Ereignis wird aufgerufen, bevor jeder Datensatz von Delta auf die zugrunde liegende Datenbank/das Dataset angewendet wird und daher der Ort, an dem diese Informationen abgerufen werden können ... Aber Showmessage beendet den Anwendungsprozess.

BEARBEITEN: Jetzt erinnerte ich mich, dass es eine andere Option gibt: Sie können Delta einer anderen clientdataset Data -Eigenschaft zuweisen und den Datensatz UpdateStatus für diesen Datensatz lesen. Natürlich müssen Sie diese vor tun ApplyUpdates tun ...

var 
    cdsAux: TClientDataset; 
begin 
    . 
    . 
    <creation of cdsAux> 
    cdsAUx.Data := cdsUpdated.Delta; 
    cdsAux.First; 
    case cdsAux.UpdateStatus of 
    usModified: 
     ShowMessage('Modified'); 
    usInserted: 
     ShowMessage('Inserted'); 
    usDeleted: 
     ShowMessage('Deleted'); // For this to work you have to modify 
           // TClientDataset.StatusFilter 
    end; 
    <cleanup code> 
end; 
+0

Das klingt sehr gut. Wenn das ApplyUpdate nur mit einem Datensatz verknüpft ist, enthält Delta Arry nur einen Eintrag, der weiß, ob es sich um ein Update oder eine Einfügung handelt. Ich brauche also nur eine Möglichkeit, auf diese Informationen im Delta zuzugreifen. – mjn

+0

Warum verwendet es eine zweite CDS? Ich würde erwarten, dass der UpdateStatus bereits in der ersten CDS verfügbar ist, also konnte ich ihn direkt lesen. Oder ist StatusFilter die Antwort, warum ein zweiter benötigt wird? – mjn

+0

Denn mit der 2. cds haben Sie nur Inhalt des Delta, und nichts mehr. Aber es ist nur eine alternative Möglichkeit, das Ding zu machen, ohne den Dataset-Provider zu durchlaufen. –

4

Before Ereignis auf TDataSetProvider wie folgt definiert ist:

procedure BeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet; DeltaDS: 
          TCustomClientDataSet; UpdateKind: TUpdateKind; 
          var Applied: Boolean); 

Parameter sagt UpdateKind was mit Rekord getan werden: ukModify, ukInsert or ukDelete . Sie können es wie folgt testen:

procedure TSomeRDM.SomeProviderBeforeUpdateRecord(Sender: TObject; 
     SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; 
     var Applied: Boolean); 
begin 
    case UpdateKind of 
    ukInsert : 
     // Process Insert; 
    ukModify : 
     // Process update 
    ukDelete : 
     // Process Delete 
    end; 
end; 

Hinweis: Diese Veranstaltung Unterschrift ist von Delphi 7. Ich weiß nicht, ob es in späteren Versionen von Delphi geändert.

2

die ClientDataSet.StatusFilter auf einen TUpdateStatus Wert gesetzt und dann lesen ClientDataSet.RecordCount

zum Beispiel

ClientDataSet1.StatusFilter := [usDeleted]; 
ShowMessage(IntToStr(ClientDataSet1.RecordCount)); 

wird die Anzahl der Delete-Abfragen zurück, die ausgeführt werden.

Beachten Sie zwei Dinge jedoch.Wenn Sie StatusFilter auf usModified setzen, werden immer sowohl die geänderten als auch die nicht geänderten Datensätze berücksichtigt. Sie erhalten also die Hälfte dieses Werts (ein Wert von 4 bedeutet, dass 2 Aktualisierungsabfragen ausgeführt werden). Das Setzen von StatusFilter auf [] (ein leeres Set) entspricht der Wiederherstellung der Standardansicht (Modified, Unmodified und Inserted)

Stellen Sie sicher, dass alle nicht hochgeladenen Änderungen veröffentlicht wurden, bevor Sie dies tun, andernfalls nicht hochgeladene Änderungen möglicherweise nicht berücksichtigt.

+0

Vielen Dank, das war das fehlende Stück der einfachsten Lösung! Sehen Sie meinen Kommentar in der Antwort von Fabricio Araujo. – mjn

Verwandte Themen