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

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 CDaoRecordsetElemente 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 rswird 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 CDaoRecordsetabgeleiteter Klasse empdurchsucht 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 in CDaoRecordset 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 GetRowseinzurichten. 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 Funktionsfunktion CDaoFieldExchange::AppendParamType an, um die Namen der einzelnen Typen anzuzeigen. DFX_TextBei 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 in DFX_Text den Informationstypen in der Struktur sehen können, gehören der verwendete DAO-Typ (DAO_CHAR oder DAO_WCHAR im Fall von DFX_Text). Darüber hinaus wird der verwendete Bindungstyp eingerichtet. In einem früheren Abschnitt GetRows 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 (z DFX_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