Ich muss versuchen, nicht-physische Felder in einem Delphi TClientDataset zu aktualisieren, das mit einer TSQLQuery verbunden ist

8

Precis: Mein Code versucht, nicht-physische Felder in einem Delphi XE TClientDataset zu aktualisieren (verbunden mit einem TSQLQuery mit seinem SQL -Eigenschaftssatz), die als Ergebnis eines Befehls runtime Open erstellt wurden .

Ich habe ein TClientDataset verbunden mit einem TDatasetProvider verbunden mit einem TSQLQuery verbunden mit einem TSQLConnection . Die ersten drei dieser Objekte sind in ein paar Klassen in einer Bibliothek eingekapselt, die ich an vielen Stellen in mehreren Projekten verwende. Diese Klassen erzeugen diese 3 Objekte zur Laufzeit und eliminieren eine signifikante Menge an repetitivem Code, was notwendig ist, da ich viele, viele dieser Triplets habe.

Ziemlich typisch lade ich TClientDataset aus einer Datenbank, indem ich einige SQL in der SQL Eigenschaft von TSQLQuery und% Open in TClientDataSet anrufe. Die Fields in TClientDataset werden über diesen Aufruf an Open ie erstellt. Sie existieren nicht vor Open .

Ich bin auf ein Problem in einer Situation gestoßen, in der drei der Felder, die in TClientDataset generiert wurden, nicht physisch sind; Das heißt, SQL macht Berechnungen, um sie zu generieren. Leider werden diese 3 Felder in TClientDataset nicht anders als die physischen Felder erstellt. ihre FieldKind ist fkData (idealerweise wäre es fkInternalCalc ), Calculated Eigenschaft ist False (idealerweise wäre es True ) und ihre ProviderFlags beinhalten pfInUpdate (was im Idealfall nicht sein sollte ). Nicht überraschend, wenn es Zeit ist, ein ApplyUpdates auf dem TClientDataset zu machen, wird eine Ausnahme ausgelöst ...

%Vor%

Ich kann diesen Fehler vermeiden, indem ich die pfInUpdate -Flags dieses Feldes im Ereignishandler TDatasetProvider OnUpdateData lösche. Allerdings erfordert diese Lösung, dass die spezifischen Feldnamen dieser Funktion bekannt sind, die in den oben erwähnten generischen Klassen liegt, wodurch die Allgemeinheit des Codes gebrochen wird.

Was ich suche, ist ein generisches Mittel, um die berechnete Natur dieser Felder an die Event-Handler-Funktion zu signalisieren.

Ich kann ihre FieldKind oder Calculated Eigenschaften (nach fkInternalCalc bzw. True ) nach dem Open Aufruf nicht ändern, da dies eine WorkCDS: Cannot perform this operation on an open dataset Ausnahmemeldung generiert. Und ich kann diese Eigenschaften nicht ändern, bevor der Open -Aufruf seit dem Fields noch nicht existiert.

Ich kann das pfInUpdate -Flag von diesen Field ProviderFlags Eigenschaften nach Open entfernen, aber das wird nicht an das "Delta" TClientDatset weitergegeben, das beim OnUpdateData Event Handler eintrifft. Ich habe auch versucht, die FieldDefs.InternalCalcField Eigenschaften des Feldes zu setzen; Auch dies wird nicht an den Delta-Datensatz übergeben.

Also, alle Signaling-Ideen, die ich versucht habe, haben nicht funktioniert. Ich wäre dankbar für neue Ideen oder einen alternativen Ansatz.

Alle Internet-Suchergebnisse, denen ich begegnet bin - einschließlich der ausgezeichneten Artikel von Cary Jensen - befassen sich mit Design-Time oder nicht-SQL-generierten Setups, die nicht auf meine Situation zutreffen.

    
Chris Bargh 22.11.2012, 03:49
quelle

2 Antworten

5

Sie können in Ihrer Klasse einen Mechanismus zur Vorkonfiguration der ProviderFlags für die einzelnen Felder erstellen, die Sie in Ihrem Update-Prozess ignorieren möchten.

Wie in den Kommentaren zu Ihrer Frage vorgeschlagen, schlage ich vor, dass Sie eine neue Methode in der Klasse erstellen, um das innere ClientDataSet zu öffnen. Die ganze Magie wird innerhalb dieser Methode stattfinden.

Erstens besteht ein einfacher Mechanismus darin, eine neue TStringList-Eigenschaft aufzunehmen, die alle Felder auflistet, die Sie ignorieren möchten und die Sie mit dem Namen vergleichen werden. Fühlen Sie sich frei, dies zu übernehmen oder einen neuen besseren Mechanismus zu erstellen. Wichtig ist, dass Sie in der Lage sind, die Felder zu identifizieren, die Sie so konfigurieren möchten.

%Vor%

Nimm es als eine Idee.

Ich habe den ganzen Code hier geschrieben, vielleicht ist die Syntax falsch, aber es zeigt die ganze Idee.

    
jachguate 22.11.2012, 07:13
quelle
1

Sie können ProviderFlags (sowie einige andere Eigenschaften) von Client zu Provider (delta) übergeben, indem Sie entsprechende optionale Parameter auf CDS setzen. Vergessen Sie nicht, IncludeInDelta param

zu setzen     
vavan 22.11.2012 12:04
quelle

Tags und Links