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 ...
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.
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.
Tags und Links windows delphi tclientdataset