TN053: 自訂 DFX 常式 DAO 資料庫類別
注意事項 |
---|
從 Visual C++ .NET 開始,Visual C++ 環境和精靈不再支援 DAO (但該版本中仍包含 DAO 類別,您仍然可以使用這些類別)。Microsoft 建議您採用 OLE DB 樣板 或 ODBC 和 MFC 的新專案。請在維護現有應用程式時再使用 DAO。 |
這份技術提示告訴您,DAO 資料錄欄位交換 (DFX) 機制。 為了瞭解這個狀況的 DFX 常式,在DFX_Text函式將做為範例的詳細說明。 為這份技術提示資訊的其他來源,您可以檢查程式碼的其他個別的 DFX 函式。 您可能不需要自訂 DFX 常式視您可能需要自訂 RFX 常式 (與 ODBC 資料庫類別使用)。
這份技術提示包含:
DFX 概觀
範例使用 DAO 資料錄欄位交換和動態繫結
DFX 的運作方式
您的自訂 DFX 例行工作做了什麼
DFX_Text 的詳細資料
DFX 概觀
DAO 資料錄欄位交換 (DFX) 機制用來簡化此程序,擷取和更新資料時使用的CDaoRecordset類別。 處理程序已經過簡化,使用資料成員的CDaoRecordset類別。 藉由衍生自CDaoRecordset,您可以加入代表資料表或查詢中的每個欄位的衍生類別中的資料成員。 這項 「 靜態繫結 」 機制很簡單,但它可能不是所有應用程式選擇的資料擷取/update 方法。 DFX 在每次變更目前的資料錄時擷取每個繫結的欄位。 如果您正在開發一個重視效能的應用程式,而無須擷取每個欄位,當變更貨幣時,「 動態繫結 」 透過CDaoRecordset::GetFieldValue和CDaoRecordset::SetFieldValue可能會選擇的資料存取方法。
注意事項 |
---|
DFX 和動態繫結並不互相排斥,因此可以使用混合式的使用靜態與動態繫結。 |
DAO 資料錄欄位交換只的範例 1: 使用
(假設CDaoRecordset — 衍生的類別CMySet尚未開啟)
// Add a new record to the customers table
myset.AddNew();
myset.m_strCustID = _T("MSFT");
myset.m_strCustName = _T("Microsoft");
myset.Update();
只有動態的繫結的範例 2: 使用
(假設使用CDaoRecordset類別, rs,並已開啟)
// 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();
範例 3: 使用的 DAO 資料錄欄位交換和動態繫結
(假設瀏覽的員工資料的CDaoRecordset-衍生的類別emp)
// 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);
DFX 的運作方式
DFX 機制以類似的方式來使用 MFC ODBC 類別的資料錄欄位交換 (RFX) 機制的運作方式。 DFX 和 RFX 都相同,但還有許多內部的不同處。 DFX 函式的設計程式,以致幾乎所有的程式碼由個別的 DFX 常式共用。 在最高等級 DFX 只會執行幾件事。
DFX 建構 SQL 選取 與 SQL 參數子句,如有必要。
DFX 建構使用 DAO 的繫結結構GetRows函式 (稍後有更多資訊)。
Dfx 還管理用來偵測已變更的欄位 (如果正在使用雙緩衝區處理) 的資料緩衝區
Dfx 還管理 NULL 和 DIRTY 狀態陣列,並更新在必要時設定值。
DFX 的心臟地帶的機制是CDaoRecordset衍生類別的DoFieldExchange函式。 將這個函式呼叫分派至適當的運算型別的個別的 DFX 函式。 在撥號之前DoFieldExchange內部的 MFC 函式設定的作業類型。 下列清單會顯示不同的操作類型和簡要說明。
作業 |
描述 |
---|---|
AddToParameterList |
建置參數子句 |
AddToSelectList |
組建 SELECT 子句 |
BindField |
設定繫結結構 |
BindParam |
設定參數值 |
修復 |
設定 NULL 狀態 |
AllocCache |
會快取配置的不乾淨的核取 |
StoreField |
將目前資料錄儲存至快取 |
LoadField |
還原快取,對成員值 |
FreeCache |
釋放快取 |
SetFieldNull |
設定欄位的狀態和 設為 NULL 的值 |
MarkForAddNew |
已變更的標記欄位如果沒有虛擬 NULL |
MarkForEdit |
標記欄位 dirty if 不符合快取 |
SetDirtyField |
將欄位標示為有問題的值 |
在下一步] 區段中,每一項作業會解釋為更詳細地DFX_Text。
若要了解有關 DAO 資料錄欄位交換處理過程最重要的是它會使用GetRows函式的CDaoRecordset物件。 DAO GetRows函式可以使用幾種方式。 這份技術提示將只會簡單介紹GetRows因為它是這份技術提示的範圍之外。
DAO GetRows能以數種方法。
它可以擷取多筆資料錄和多個欄位的資料一次。 這可讓複雜的處理大型資料結構和每個欄位的適當位移與更快速存取資料和資料結構中的每一筆記錄。 MFC 並不會運用此擷取機制的多個記錄。
另一種方法GetRows可以工作比較可以讓程式設計人員指定的每一個欄位的一筆記錄的資料擷取的資料繫結位址。
DAO 會也"回呼 」 至呼叫端的可變長度資料行以便讓呼叫端配置的記憶體。 這個第二個的功能有好處的最小化資料的列印份數,以及允許的資料直接儲存到類別的成員 ( CDaoRecordset衍生的類別)。 這個第二個機制是 MFC 用來繫結至資料成員中的方法CDaoRecordset衍生類別。
您的自訂 DFX 例行工作做了什麼
很明顯的任何 DFX 函式中實作最重要作業必須能夠設定必要的資料結構,以成功地呼叫這個問題討論GetRows。 有一些其他的 DFX 函式必須也支援的作業,但無為重要或做為正確地準備進行複雜的GetRows呼叫。
DFX 使用線上文件中描述。 基本上,有兩項需求。 首先,必須新增成員到CDaoRecordset衍生類別的每個繫結的欄位和參數。 接下來CDaoRecordset::DoFieldExchange則應覆寫。 請注意該成員的資料型別是很重要。 它應該符合資料庫中欄位的資料,或至少能將轉換成該型別。 比方說,在資料庫中,如 [長整數,數值欄位可以永遠轉換成文字,繫結至CString成員,但在資料庫中的文字欄位不一定可以轉換成數值的表示,例如長整數和長整數成員繫結。 DAO 和 Microsoft Jet 資料庫引擎負責轉換 (而非 MFC)。
DFX_Text 的詳細資料
前面提過,若要說明 DFX 的運作方式,最好是利用一個範例。 此時,瀏覽的內部資訊DFX_Text應該運作以保護至少有基本了解 DFX 的效果非常好。
AddToParameterList
這項作業會建立 SQL 參數子句 ("Parameters <param name>, <param type> ... ;") 所需的 Jet。 每個參數可命名和型別 (為 RFX 呼叫中指定)。 此函式,請參閱 CDaoFieldExchange::AppendParamType 函數,查看個別型別的名稱。 如果是DFX_Text,使用的型別是text。AddToSelectList
建置 SQL 選取子句。 這相當直截了當現狀 DFX 呼叫所指定的資料行名稱只是附加 ("SELECT <column name>, ...")。BindField
最複雜的作業。 如先前所提這是 DAO 的繫結結構會利用GetRows的設定。 您可以避免惡意程式碼中看到DFX_Text的結構中的資訊類型包括使用 DAO 型別 (DAO_CHAR 或 DAO_WCHAR 的情況下DFX_Text)。 此外,使用的繫結的型別也設定。 在先前章節GetRows所述只會簡單,但它是足以解釋使用 mfc 的繫結的型別永遠是直接地址繫結 (DAOBINDING_DIRECT)。 以外的地方的可變長度資料行繫結 (就像DFX_Text),這樣 MFC 可以控制在記憶體配置和指定的位址是正確的長度,使用回呼資料繫結。 這表示該 MFC 永遠可以辨識 DAO"where"放入資料,因此允許直接與成員變數繫結。 繫結結構的其餘部分會填入之類的記憶體配置的回呼函式和資料行繫結 (繫結的資料行名稱) 的型別位址。BindParam
這是一種簡單的作業,會呼叫SetParamValue與您的成員參數中所指定的參數值。修復
在 [填滿 NULL 的每個欄位的狀態。SetFieldNull
這項作業只會標記每個欄位的狀態就會與 NULL 並將成員變數的值設為 PSEUDO_NULL。SetDirtyField
呼叫SetFieldValue的每個欄位標示有問題。
所有剩下的作業只能處理使用資料快取。 資料快取是一個額外的緩衝區中目前用來使某些事情更簡單的資料錄的資料。 舉個例說,可以自動偵測"dirty"的欄位。 線上文件中所述就可以關閉完全或在欄位層級。 緩衝區的實作會使用對應。 這個對應用來動態配置的資料複本的 「 結合 」 欄位的位址配對 (或CDaoRecordset衍生的資料成員)。
AllocCache
以動態方式配置快取的欄位值,並將其加入到對應。FreeCache
刪除快取的欄位值並從對應中移除它。StoreField
將目前的欄位值複製到的資料快取中。LoadField
會將快取的值複製到該欄位的成員。MarkForAddNew
檢查目前的欄位值是否為非-NULL ,並將它標記為已變更,如有必要。MarkForEdit
比較目前的欄位值,與資料快取並將標記不乾淨,如有必要。
提示
建立您自訂的 DFX 常式模型現有 DFX 常式標準資料型別上。