Share via


DAO Record Field Exchange: How DFX Works

OverviewHow Do IFAQSampleODBC Driver List

This article explains the DFX process. This is a fairly advanced topic, covering:

  • DFX and the recordset

  • The DFX process

****Note   ****This article is about the DAO version of record field exchange. If you are using the MFC ODBC classes rather than the MFC DAO classes, see the article Record Field Exchange: How RFX Works instead.

DFX and the Recordset

The recordset object’s field data members, taken together, constitute an edit buffer that holds the selected columns of one record. When the recordset is first opened and is about to read the first record, DFX binds (associates) each selected column to the address of the appropriate field data member. When the recordset updates a record, DFX calls DAO to send the appropriate commands to the database engine. DFX uses its knowledge of the field data members to specify the columns (fields) in the data source to write.

There are two ways of working with the edit buffer in a recordset:

  • Use MFC’s “double-buffering” mechanism.

    By default, your recordsets keep a second copy of the edit buffer for most data types (excluding the variable-length types, such as text and binary data). The copy is used for comparison with the edit buffer, to detect changes. You can choose to turn double buffering off, but keeping it turned on simplifies managing record field updates, adding and deleting records, and so on. For more information about double buffering, see the article DAO Record Field Exchange: Double Buffering Records.

  • Don’t use double buffering; instead, manage all field activity yourself.

    If you turn off the default double buffering, each time you edit a field you must call and (passing the parameter FALSE). That is, you must take explicit actions so MFC does not have to compare the edit buffer with a copy to detect your changes. For more information, see the article DAO Record Field Exchange: Double Buffering Records.

If you have double buffering enabled (the default), the framework backs up the edit buffer at certain stages so it can restore its contents if necessary. With double buffering enabled, DFX backs up the edit buffer before adding a new record and before editing an existing record. It restores the edit buffer in some cases — for example, after an call following .

Besides exchanging data between the data source and the recordset’s field data members, DFX manages binding parameters. When the recordset is opened, any parameter data members are bound in the order of the named parameters in the SQL statement that receives or constructs. For more information, see the article DAO Queries: Filtering and Parameterizing Queries.

Your recordset class’s override of does all the work, moving data in both directions. Like dialog data exchange (DDX), DFX needs information about the data members of your class. ClassWizard provides the necessary information by writing a recordset-specific implementation of DoFieldExchange for you, based on the field data member names and data types you specify with the wizard.

The DAO Record Field Exchange Process

This section describes the sequence of DFX events as a recordset object is opened and as you scroll and add, update, and delete records. The table Using DFX: You and the Framework in the article DAO Record Field Exchange: Using DFX shows the process at a high level, illustrating operations as a recordset is opened. The table Sequence of DFX Operations During Recordset Open and the table Sequence of DFX Operations During Scrolling in this article show the process as DFX processes a Move command in the recordset and as DFX manages an update. During these processes, is called to perform many different operations. The data member of the object determines which operation is requested.

DFX: Initial Binding of Columns and Parameters

The following DFX activities occur, in the order shown, when you call a recordset object’s member function:

  • If the recordset has parameter data members, the framework calls to bind the parameters to named parameters in the recordset’s SQL statement.

  • The framework calls DoFieldExchange a second time to bind the columns to corresponding field data members in the recordset. This establishes the recordset object as an edit buffer containing the columns of the first record.

  • The recordset opens either a table-type recordset or an SQL-based recordset (dynaset or snapshot) and selects the first record. The record’s columns are loaded into the recordset’s field data members.

The following table shows the sequence of DFX operations when you open a recordset.

Sequence of DFX Operations During Recordset Open

Your operation DoFieldExchange operation Database operation
1. Open the recordset.
2. Build an SQL statement. DoFieldExchange might have a querydef, a tabledef, or an SQL statement handed to it. If not, MFC builds the statement.
3. Open the querydef or tabledef, or create a temporary querydef (using either an SQL statement passed in or one built by MFC) and open it.
4. Bind parameter data member(s).
5. Bind field data member(s) to column(s).
6. Create the recordset.
7. DAO moves to the first record and fills in the data.
8. Fix up the data for C++.

DFX: Scrolling

When you scroll from one record to another, the framework calls to replace the values previously stored in the field data members with values for the new record.

The following table shows the sequence of DFX operations when the user moves from record to record.

Sequence of DFX Operations During Scrolling

Your operation DoFieldExchange operation Database operation
1. Call or one of the other Move functions.
2. DAO does the move and fills in the data.
3. Fix up the data for C++.

DFX: Adding New Records and Editing Existing Records

If you add a new record, the recordset operates as an edit buffer to build up the contents of the new record. As with adding records, editing records involves changing the values of the recordset’s field data members. From the DFX perspective, the sequence is as follows:

  1. If double buffering is on, your call to the recordset’s or member function causes DFX to store the current edit buffer so it can be restored later.

  2. If double buffering is on, AddNew or Edit prepares the fields in the edit buffer so DFX can detect changed field data members. If double buffering is off for an Edit call, the fields are not prepared for detection. (In this case, it’s up to you to manage edits explicitly — see the article DAO Record Field Exchange: Double Buffering Records.) The fields of a record prepared for AddNew are set to null whether double buffering is in effect or not.

    Since a new record has no previous values to compare new ones with, AddNew (with double buffering) sets the value of each field data member to a PSEUDO_NULL value as described under . Later, when you call , DFX compares each data member’s value with the PSEUDO_NULL value; if there’s a difference, the data member has been set. (PSEUDO_NULL is not the same thing as a record column with a true Null value; nor is either the same as C++ NULL.) 

    ****Note   ****MFC does not use a PSEUDO_NULL value for or fields. Those data types have Nulls built in.

    Unlike the Update call for AddNew, the Update call for Edit compares updated values with previously stored values rather than using PSEUDO_NULL, if double buffering is on. If double buffering is off, you must call after an edit (and if appropriate). The difference between Edit and AddNew is that AddNew has no previous stored values for comparison.

  3. You directly set the values of field data members whose values you want to edit or that you want filled for a new record. (This can include calling SetFieldNull.)

  4. If double buffering is on, your call to checks for changed field data members, as described in step 2 (see the table Sequence of DFX Operations During Scrolling). If none have changed, Update returns 0. If some field data members have changed, Update propagates the changes to the database.

  5. For AddNew, Update concludes by restoring the previously stored values of the record that was current before the AddNew call. For Edit, the new, edited values remain in place if double buffering is in effect.

The following table shows the sequence of DFX operations when you add a new record or edit an existing record.

Sequence of DFX Operations During AddNew and Edit

Your operation DoFieldExchange operation Database operation
1. Call or .
2. Back up the edit buffer if double buffering is on.
3. For AddNew, mark field data members as “clean” and Null. For Edit, call Edit in DAO.
4. Assign values to recordset field data members.
5. Call Update.
6. Check for changed fields if double buffering is on.
7. Propagate changes to the database. Call Update in DAO.
8. For AddNew, restore the edit buffer to its backed-up contents if double buffering is on. If it is off, the values set for the new record remain in the recordset data members. For Edit, delete the backup if double buffering is on.
9. If double buffering is off, you must refresh the current record after AddNew. Call with the AFX_MOVE_REFRESH parameter to restore the record that was previously current.

DFX: Deleting Existing Records

When you delete a record, DFX sets all the fields to NULL as a reminder that the record is deleted and you must move off it. You won’t need any other DFX sequence information.

In the Class Library Reference see , , and, under Macros and Globals, .

See Also   DAO: Where Is..., DAO Record Field Exchange (DFX), DAO Record Field Exchange: Using DFX, DAO Record Field Exchange: Working with the Wizard Code, DAO Record Field Exchange: Using the DFX Functions, ClassWizard