TN053: Benutzereigene DFX-Routinen für DAO-Datenbankklassen
Hinweis
DAO wird mit Access-Datenbanken verwendet und wird über Office 2013 unterstützt. DAO 3.6 ist die letzte Version und gilt als veraltet. Die Visual C++-Umgebung und -Assistenten unterstützen DAO nicht (obwohl die DAO-Klassen enthalten sind und Sie sie weiterhin verwenden können). Microsoft empfiehlt, OLE DB-Vorlagen oder ODBC- und MFC für neue Projekte zu verwenden. Sie sollten DAO nur in Standard vorhandenen Anwendungen verwenden.
In diesem technischen Hinweis wird der DAO-Datensatzaustauschmechanismus (DFX) beschrieben. Um zu verstehen, was in den DFX-Routinen passiert, wird die DFX_Text
Funktion im Detail als Beispiel erläutert. Als zusätzliche Informationsquelle für diese technische Notiz können Sie den Code für die anderen DFX-Funktionen untersuchen. Wahrscheinlich benötigen Sie keine benutzerdefinierte DFX-Routine so oft, wie Sie möglicherweise eine benutzerdefinierte RFX-Routine (verwendet mit ODBC-Datenbankklassen) benötigen.
Diese technische Anmerkung enthält:
DFX-Übersicht
Beispiele für DAO-Datensatzfeldaustausch und dynamische Bindung
DFX-Übersicht
Der DAO-Datensatzfeldaustauschmechanismus (DFX) wird verwendet, um das Abrufen und Aktualisieren von Daten bei Verwendung der CDaoRecordset
Klasse zu vereinfachen. Der Prozess wird vereinfacht, indem Datenmmber der CDaoRecordset
Klasse verwendet werden. Durch ableitende CDaoRecordset
Elemente können Sie der abgeleiteten Klasse Datenmember hinzufügen, die jedes Feld in einer Tabelle oder Abfrage darstellt. Dieser Mechanismus für statische Bindung ist einfach, aber es ist möglicherweise nicht die Methode zum Abrufen/Aktualisieren von Daten für alle Anwendungen. DFX ruft jedes gebundene Feld bei jeder Änderung des aktuellen Datensatzes ab. Wenn Sie eine leistungssensitive Anwendung entwickeln, die nicht jedes Feld abrufen muss, wenn Währung geändert wird, "dynamische Bindung" über CDaoRecordset::GetFieldValue
und CDaoRecordset::SetFieldValue
kann die Datenzugriffsmethode sein.
Hinweis
DFX und dynamische Bindung schließen sich nicht gegenseitig aus, sodass eine hybride Verwendung statischer und dynamischer Bindung verwendet werden kann.
Beispiel 1 – Nur Verwendung von DAO-Datensatzfeld-Exchange
(geht davon aus CDaoRecordset
, dass abgeleitete Klasse CMySet
bereits geöffnet ist)
// Add a new record to the customers table
myset.AddNew();
myset.m_strCustID = _T("MSFT");
myset.m_strCustName = _T("Microsoft");
myset.Update();
Beispiel 2 – Nur dynamische Bindung
(setzt voraus, dass CDaoRecordset
die Klasse verwendet rs
wird und bereits geöffnet ist)
// Add a new record to the customers table
COleVariant varFieldValue1 (_T("MSFT"),
VT_BSTRT);
//Note: VT_BSTRT flags string type as ANSI,
instead of UNICODE default
COleVariant varFieldValue2 (_T("Microsoft"),
VT_BSTRT);
rs.AddNew();
rs.SetFieldValue(_T("Customer_ID"),
varFieldValue1);
rs.SetFieldValue(_T("Customer_Name"),
varFieldValue2);
rs.Update();
Beispiel 3 – Verwendung von DAO Record Field Exchange und dynamischer Bindung
(geht davon aus, dass Mitarbeiterdaten mit CDaoRecordset
abgeleiteter Klasse emp
durchsucht werden)
// Get the employee's data so that it can be displayed
emp.MoveNext();
// If user wants to see employee's photograph,
// fetch it
COleVariant varPhoto;
if (bSeePicture)
emp.GetFieldValue(_T("photo"),
varPhoto);
// Display the data
PopUpEmployeeData(emp.m_strFirstName,
emp.m_strLastName,
varPhoto);
Funktionsweise von DFX
Der DFX-Mechanismus funktioniert ähnlich wie der RFX-Mechanismus (Record Field Exchange), der von den MFC ODBC-Klassen verwendet wird. Die Prinzipien von DFX und RFX sind identisch, aber es gibt zahlreiche interne Unterschiede. Der Entwurf der DFX-Funktionen war so, dass praktisch der gesamte Code von den einzelnen DFX-Routinen gemeinsam genutzt wird. DfX auf höchster Ebene erledigt nur ein paar Dinge.
DFX erstellt die SQL SELECT-Klausel und die SQL PARAMETERS-Klausel bei Bedarf.
DFX erstellt die Bindungsstruktur, die von der DAO-Funktion
GetRows
verwendet wird (weiter unten).DFX verwaltet den Datenpuffer, der verwendet wird, um modifiziert Felder zu erkennen (wenn doppelter Puffer verwendet wird)
DFX verwaltet die NULL- und DIRTY-Statusarrays und legt bei Bedarf Werte fest.
Im Mittelpunkt des DFX-Mechanismus steht die Funktion der CDaoRecordset
abgeleiteten Klasse DoFieldExchange
. Diese Funktion verteilt Aufrufe an die einzelnen DFX-Funktionen eines geeigneten Vorgangstyps. Vor dem Aufrufen DoFieldExchange
der internen MFC-Funktionen legen Sie den Vorgangstyp fest. In der folgenden Liste sind die verschiedenen Vorgangstypen und eine kurze Beschreibung aufgeführt.
Vorgang | Beschreibung |
---|---|
AddToParameterList |
Builds PARAMETERS-Klausel |
AddToSelectList |
Builds SELECT-Klausel |
BindField |
Einrichten der Bindungsstruktur |
BindParam |
Legt Parameterwerte fest |
Fixup |
Legt den NULL-Status fest. |
AllocCache |
Ordnet den Cache für modifiziert Überprüfung zu. |
StoreField |
Speichert den aktuellen Datensatz im Cache. |
LoadField |
Wiederherstellen des Caches in Memberwerten |
FreeCache |
Freigeben des Caches |
SetFieldNull |
Legt den Feldstatus und -wert auf NULL fest. |
MarkForAddNew |
Markiert Felder modifiziert, wenn nicht PSEUDO NULL |
MarkForEdit |
Markiert Felder modifiziert, wenn sie nicht mit dem Cache übereinstimmen |
SetDirtyField |
Legt Feldwerte fest, die als modifiziert |
Im nächsten Abschnitt wird jeder Vorgang ausführlicher erläutert für DFX_Text
.
Das wichtigste Feature, das Sie über den DAO-Datensatzfeldaustauschprozess verstehen sollten, ist, dass es die GetRows
Funktion des CDaoRecordset
Objekts verwendet. Die DAO-Funktion GetRows
kann auf verschiedene Arten funktionieren. Diese technische Anmerkung wird nur kurz beschreiben GetRows
, da sie außerhalb des Umfangs dieses technischen Hinweises liegt.
DAO GetRows
kann auf verschiedene Arten funktionieren.
Sie kann mehrere Datensätze und mehrere Datenfelder gleichzeitig abrufen. Dies ermöglicht einen schnelleren Datenzugriff mit der Komplikation des Umgangs mit einer großen Datenstruktur und den entsprechenden Offsets für jedes Feld und für jeden Datensatz der Daten in der Struktur. MFC nutzt diesen Mechanismus zum Abrufen mehrerer Datensätze nicht.
Eine weitere Möglichkeit
GetRows
besteht darin, Programmierern das Angeben von Bindungsadressen für die abgerufenen Daten jedes Felds für einen Datensatz von Daten zu ermöglichen.DAO ruft den Aufrufer auch für Spalten mit variabler Länge zurück, um dem Aufrufer das Zuweisen von Arbeitsspeicher zu ermöglichen. Dieses zweite Feature hat den Vorteil, die Anzahl der Kopien von Daten zu minimieren und die direkte Speicherung von Daten in Membern einer Klasse (die
CDaoRecordset
abgeleitete Klasse) zu ermöglichen. Dieser zweite Mechanismus ist die Methode MFC, die zum Binden an Datenmmber inCDaoRecordset
abgeleiteten Klassen verwendet wird.
Funktionsweise Ihrer benutzerdefinierten DFX-Routine
Aus dieser Diskussion geht hervor, dass der wichtigste in jeder DFX-Funktion implementierte Vorgang die Möglichkeit sein muss, die erforderlichen Datenstrukturen zum erfolgreichen Aufruf GetRows
einzurichten. Es gibt eine Reihe anderer Vorgänge, die eine DFX-Funktion ebenfalls unterstützen muss, aber keine so wichtig oder komplex wie die ordnungsgemäße Vorbereitung des GetRows
Anrufs.
Die Verwendung von DFX wird in der Onlinedokumentation beschrieben. Im Wesentlichen gibt es zwei Anforderungen. Zunächst müssen Elemente der CDaoRecordset
abgeleiteten Klasse für jedes gebundene Feld und jeden Parameter hinzugefügt werden. Im Anschluss sollte dies CDaoRecordset::DoFieldExchange
außer Kraft gesetzt werden. Beachten Sie, dass der Datentyp des Elements wichtig ist. Sie sollte mit den Daten aus dem Feld in der Datenbank übereinstimmen oder zumindest in diesen Typ wandeln. Beispielsweise kann ein numerisches Feld in einer Datenbank, z. B. eine lange ganze Zahl, immer in Text konvertiert und an ein CString
Element gebunden werden, aber ein Textfeld in einer Datenbank kann möglicherweise nicht unbedingt in eine numerische Darstellung konvertiert werden, z. B. eine lange ganze Zahl und gebunden an ein langes ganzzahliges Element. DAO und das Microsoft Jet-Datenbankmodul sind für die Konvertierung (anstelle von MFC) verantwortlich.
Details zu DFX_Text
Wie zuvor Erwähnung beschrieben, ist die beste Methode, um zu erläutern, wie DFX funktioniert, um ein Beispiel zu durchlaufen. Dazu sollten die Internen von DFX_Text
DFX ziemlich gut funktionieren, um zumindest ein grundlegendes Verständnis von DFX zu bieten.
AddToParameterList
Mit diesem Vorgang wird die sql PARAMETERS-Klausel ("
Parameters <param name>, <param type> ... ;
") erstellt, die von Jet benötigt wird. Jeder Parameter wird benannt und eingegeben (wie im RFX-Aufruf angegeben). Sehen Sie sich die FunktionsfunktionCDaoFieldExchange::AppendParamType
an, um die Namen der einzelnen Typen anzuzeigen.DFX_Text
Bei diesem Typ handelt es sich um Text.AddToSelectList
Erstellt die SQL SELECT-Klausel . Dies ist ziemlich direkt vorwärts, da der durch den DFX-Aufruf angegebene Spaltenname einfach angefügt wird ("
SELECT <column name>, ...
").BindField
Die komplexesten Vorgänge. Wie Erwähnung zuvor erwähnt, wird die von
GetRows
ihnen verwendete DAO-Bindungsstruktur eingerichtet. Wie Sie aus dem Code inDFX_Text
den Informationstypen in der Struktur sehen können, gehören der verwendete DAO-Typ (DAO_CHAR oder DAO_WCHAR im Fall vonDFX_Text
). Darüber hinaus wird der verwendete Bindungstyp eingerichtet. In einem früheren AbschnittGetRows
wurde nur kurz beschrieben, aber es reichte aus, zu erläutern, dass der von MFC verwendete Bindungstyp immer direkte Adressbindung (DAOBINDING_DIRECT) ist. Zusätzlich zur Bindung variabler Spalten (zDFX_Text
. B. ) wird eine Rückrufbindung verwendet, sodass MFC die Speicherzuweisung steuern und eine Adresse der richtigen Länge angeben kann. Dies bedeutet, dass MFC immer DAO "wo" die Daten anweisen kann, sodass die Bindung direkt an Membervariablen ermöglicht wird. Der Rest der Bindungsstruktur wird mit Elementen wie der Adresse der Rückruffunktion für die Speicherzuweisung und dem Typ der Spaltenbindung (Bindung nach Spaltenname) ausgefüllt.BindParam
Dies ist ein einfacher Vorgang, der mit dem parameterwert aufgerufen wird
SetParamValue
, der im Parametermemm angegeben ist.Fixup
Füllt den NULL-Status für jedes Feld aus.
SetFieldNull
Dieser Vorgang markiert nur jeden Feldstatus als NULL und legt den Wert der Membervariable auf PSEUDO_NULL fest.
SetDirtyField
Aufrufe
SetFieldValue
für jedes Feld, das modifiziert markiert ist.
Alle Erneut Standard vorgänge behandeln nur die Verwendung des Datencaches. Der Datencache ist ein zusätzlicher Puffer der Daten im aktuellen Datensatz, der verwendet wird, um bestimmte Dinge zu vereinfachen. Beispielsweise können "modifiziert"-Felder automatisch erkannt werden. Wie in der Onlinedokumentation beschrieben, kann sie vollständig oder auf Feldebene deaktiviert werden. Die Implementierung des Puffers verwendet eine Zuordnung. Diese Zuordnung wird verwendet, um dynamisch zugeordnete Kopien der Daten mit der Adresse des "gebundenen" Felds (oder CDaoRecordset
abgeleiteten Datenmemm) abzugleichen.
AllocCache
Weist den zwischengespeicherten Feldwert dynamisch zu und fügt ihn der Karte hinzu.
FreeCache
Löscht den zwischengespeicherten Feldwert und entfernt ihn aus der Zuordnung.
StoreField
Kopiert den aktuellen Feldwert in den Datencache.
LoadField
Kopiert den zwischengespeicherten Wert in das Feldelement.
MarkForAddNew
Überprüft, ob der aktuelle Feldwert ungleich NULL ist, und markiert ihn bei Bedarf modifiziert.
MarkForEdit
Vergleicht den aktuellen Feldwert mit dem Datencache und markiert bei Bedarf modifiziert.
Tipp
Modellieren Sie Ihre benutzerdefinierten DFX-Routinen für die vorhandenen DFX-Routinen für Standarddatentypen.
Siehe auch
Technische Hinweise – nach Nummern geordnet
Technische Hinweise – nach Kategorien geordnet