Datensatzfeldaustausch: Arbeiten mit Assistenten-Code
In diesem Thema werden der vom MFC-Anwendungs-Assistenten und von Klasse hinzufügen eingefügte Code zur Unterstützung von RFX erläutert (wie beschrieben unter Hinzufügen eines MFC-ODBC-Consumers). Des Weiteren wird dort erläutert, wie dieser Code geändert werden kann.
Tipp
Dieses Thema bezieht sich auf von CRecordset abgeleitete Objekte, in denen das gesammelte Abrufen von Zeilen nicht implementiert wurde. Beim gesammelten Abrufen von Zeilen wird der Sammel-Datensatzfeldaustausch (Bulk-RFX) implementiert. Der Bulk-RFX ist mit RFX vergleichbar. Unter Recordset: Abrufen von Datensätzen in einer Sammeloperation (ODBC) werden die Unterschiede erläutert.
Wenn Sie mit dem MFC-Anwendungs-Assistenten oder Klasse hinzufügen eine Recordset-Klasse erstellen, erstellt der Assistent auf der Basis der von Ihnen getroffenen Auswahl von Datenquelle, Tabelle und Spalte die folgenden RFX-bezogenen Elemente:
Deklarationen der Felddatenmember des Recordsets in der Recordset-Klasse
Überschreiben von CRecordset::DoFieldExchange
Eine Initialisierung der Recordset-Felddatenmember im Konstruktor der Recordset-Klasse.
Felddatenmember-Deklarationen
Durch die Assistenten wird in eine H-Datei eine Deklaration der Recordset-Klasse geschrieben, die für die CSections-Klasse wie folgt aussehen könnte:
class CSections : public CRecordset
{
public:
CSections(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CSections)
// Field/Param Data
CString m_strCourseID;
CString m_strInstructorID;
CString m_strRoomNo;
CString m_strSchedule;
CString m_strSectionNo;
// Overrides
// Wizard generated virtual function overrides
protected:
virtual CString GetDefaultConnect(); // Default connection string
virtual CString GetDefaultSQL(); // Default SQL for Recordset
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support
// Implementation
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
};
Falls Sie Parameterdatenmember oder neue Felddatenmember hinzufügen möchten, die Sie selbst binden, fügen Sie diese hinter denen ein, die durch den Assistenten erstellt wurden.
Beachten Sie, dass der Assistent die DoFieldExchange-Memberfunktion der CRecordset-Klasse überschreibt.
Überschreiben von DoFieldExchange
DoFieldExchange bildet das Kernstück von RFX. DoFieldExchange wird durch das Framework immer dann aufgerufen, wenn Daten zwischen Datenquelle und Recordset transferiert werden müssen. DoFieldExchange unterstützt darüber hinaus das Ermitteln von Informationen über Felddatenmember durch die IsFieldDirty-Memberfunktion und die IsFieldNull-Memberfunktion.
Die folgende DoFieldExchange-Überschreibung gilt der CSections-Klasse. Der Assistent fügt die Funktion in die CPP-Datei der Recordset-Klasse ein.
void CSections::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, "CourseID", m_strCourseID);
RFX_Text(pFX, "InstructorID", m_strInstructorID);
RFX_Text(pFX, "RoomNo", m_strRoomNo);
RFX_Text(pFX, "Schedule", m_strSchedule);
RFX_Text(pFX, "SectionNo", m_strSectionNo);
}
Beachten Sie bei dieser Funktion folgende, besonders wichtige Features:
Dieser Abschnitt der Funktion wird als Feldzuordnung bezeichnet.
Ein Aufruf von CFieldExchange::SetFieldType über den Zeiger pFX. Durch diesen Aufruf wird festgelegt, dass alle RFX-Funktionsaufrufe bis zum Ende von DoFieldExchange oder bis zum nächsten Aufruf von SetFieldType Ausgabespalten sind. Weitere Informationen hierzu finden Sie unter CFieldExchange::SetFieldType.
Mehrere Aufrufe der globalen Funktion RFX_Text, und zwar ein Aufruf pro Felddatenmember (die in diesem Beispiel alle CString-Variablen sind). Durch diese Aufrufe wird die Beziehung zwischen einem Spaltennamen der Datenquelle und einem Felddatenmember festgelegt. Die RFX-Funktionen führen den eigentlichen Datentransfer durch. Die Klassenbibliothek stellt für alle wichtigen Datentypen RFX-Funktionen zur Verfügung. Weitere Informationen über RFX-Funktionen finden Sie unter Datensatzfeldaustausch: Verwenden der RFX-Funktionen.
Tipp
Die Reihenfolge der Spalten in einem Resultset muss mit der Reihenfolge der RFX-Funktionsaufrufe in DoFieldExchange übereinstimmen.
Der Zeiger pFX verweist auf ein CFieldExchange-Objekt, das vom Framework beim Aufruf von DoFieldExchange übergeben wird. Das CFieldExchange-Objekt gibt unter anderem an, welche Operation DoFieldExchange ausführen soll und in welcher Richtung der Datentransfer stattfindet.
Recordset-Konstruktor
Der von den Assistenten erstellte Recordset-Konstruktor enthält zwei RFX-bezogene Elemente:
Eine Initialisierung für jeden Felddatenmember;
Eine Initialisierung für den Datenmember m_nFields, der die Anzahl der Felddatenmember enthält.
Der Konstruktor für das CSections-Recordset-Beispiel sieht wie folgt aus:
CSections::CSections(CDatabase* pdb)
: CRecordset(pdb)
{
m_strCourseID = "";
m_strInstructorID = "";
m_strRoomNo = "";
m_strSchedule = "";
m_strSectionNo = "";
m_nFields = 5;
}
Tipp
Wenn Sie beliebige Felddatenmember von Hand hinzufügen, um z. B. neue Spalten dynamisch zu binden, müssen Sie m_nFields inkrementieren. Verwenden Sie hierzu eine neue Codezeile wie die Folgende:
m_nFields += 3;
Dieser Code bedeutet, dass drei neue Felder hinzugefügt werden. Falls Sie Parameterdatenmember hinzufügen, müssen Sie den Datenmember m_nParams initialisieren, der die Anzahl der Parameterdatenmember enthält. Fügen Sie die m_nParams-Initialisierung außerhalb der Klammern ein.