Record Field Exchange: Working with the Wizard Code

HomeOverviewHow Do IFAQSampleTutorialODBC Driver List

This article explains the code that AppWizard and ClassWizard write to support RFX and how you might want to alter that code.

Note   This article applies to classes derived from CRecordset in which bulk row fetching has not been implemented. If you are using bulk row fetching, then bulk record field exchange (Bulk RFX) is implemented. Bulk RFX is similar to RFX. To understand the differences, see the article Recordset: Fetching Records in Bulk (ODBC).

When you create a recordset class with ClassWizard (or with AppWizard), the wizard writes the following RFX-related elements for you, based on the data source, table, and column choices you make in the wizard:

The Field Data Member Declarations

The wizards write a recordset class declaration in an .H file that resembles the following for class CSections:

class CSections : public CRecordset
{
public:
    CSections(CDatabase* pDatabase);
    CSections::~CSections();

// Field/Param Data
    //{{AFX_FIELD(CSections, CRecordset)
    CString   m_strCourseID;
    CString   m_strInstructorID;
    CString   m_strRoomNo;
    CString   m_strSchedule;
    CString   m_strSectionNo;
    //}}AFX_FIELD 

// Implementation
protected:
    virtual CString GetDefaultConnect();   // Default connection string
    virtual CString GetDefaultSQL();    // Default SQL for Recordset
    virtual void DoFieldExchange(CFieldExchange* pFX);  // RFX support
    DECLARE_DYNAMIC(CSections)
};

Notice the following key features about the class above:

Caution    Never edit the code inside “//{{AFX” brackets. Always use ClassWizard. If you add parameter data members or new field data members that you bind yourself, add them outside the brackets.

The DoFieldExchange Override

DoFieldExchange is the heart of RFX. The framework calls DoFieldExchange any time it needs to move data either from data source to recordset or from recordset to data source. DoFieldExchange also supports obtaining information about field data members through the IsFieldDirty and IsFieldNull member functions.

The following DoFieldExchange override is for the CSections class. ClassWizard writes the function in the .CPP file for your recordset class.

void CSections::DoFieldExchange(CFieldExchange* pFX)
{
    //{{AFX_FIELD_MAP(CSections)
    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);
    //}}AFX_FIELD_MAP
}

Notice the following key features of the function:

The Recordset Constructor

The recordset constructor that the wizards write contains two things related to RFX:

The constructor for the CSections recordset example looks like this:

CSections::CSections(CDatabase* pdb)
    : CRecordset(pdb)
{
    //{{AFX_FIELD_INIT(CSections)
    m_strCourseID = "";
    m_strInstructorID = "";
    m_strRoomNo = "";
    m_strSchedule = "";
    m_strSectionNo = "";
    m_nFields = 5;
    //}}AFX_FIELD_INIT 
}

Important   If you add any field data members manually, as you might if you bind new columns dynamically, you must increment m_nFields. Do so with another line of code outside the “//{{AFX_FIELD_INIT” brackets:

    m_nFields += 3;

This is the code for adding three new fields. If you add any parameter data members, you must initialize the m_nParams data member, which contains the number of parameter data members. Put the m_nParams initialization outside the brackets.