TN053: routine DFX personalizzate per le classi database DAO

Nota

DAO viene usato con i database di Access ed è supportato tramite Office 2013. DAO 3.6 è la versione finale e viene considerata obsoleta. L'ambiente e le procedure guidate di Visual C++ non supportano DAO (anche se le classi DAO sono incluse ed è comunque possibile usarle). Microsoft consiglia di usare i modelli OLE DB o ODBC e MFC per i nuovi progetti. È consigliabile usare DAO solo per gestire le applicazioni esistenti.

Questa nota tecnica descrive il meccanismo DFX (DAO Record Field Exchange). Per comprendere cosa accade nelle routine DFX, la DFX_Text funzione verrà illustrata in dettaglio come esempio. Come fonte aggiuntiva di informazioni a questa nota tecnica, è possibile esaminare il codice per le altre funzioni DFX singole. Probabilmente non sarà necessaria una routine DFX personalizzata come spesso potrebbe essere necessaria una routine RFX personalizzata (usata con classi di database ODBC).

Questa nota tecnica contiene:

Panoramica di DFX

Il meccanismo di scambio dei campi dei record DAO (DFX) viene usato per semplificare la procedura di recupero e aggiornamento dei dati quando si usa la CDaoRecordset classe . Il processo è semplificato usando i membri dati della CDaoRecordset classe . Derivando da CDaoRecordsetè possibile aggiungere membri dati alla classe derivata che rappresenta ogni campo di una tabella o di una query. Questo meccanismo di "associazione statica" è semplice, ma potrebbe non essere il metodo di recupero/aggiornamento dei dati scelto per tutte le applicazioni. DFX recupera ogni campo associato ogni volta che il record corrente viene modificato. Se si sviluppa un'applicazione sensibile alle prestazioni che non richiede il recupero di ogni campo quando viene modificata la valuta, l'associazione dinamica tramite CDaoRecordset::GetFieldValue e CDaoRecordset::SetFieldValue può essere il metodo di accesso ai dati scelto.

Nota

DFX e l'associazione dinamica non si escludono a vicenda, quindi è possibile usare un uso ibrido di binding statico e dinamico.

Esempio 1 : utilizzo solo di scambio di campi record DAO

(presuppone CDaoRecordset : classe CMySet derivata già aperta)

// Add a new record to the customers table
myset.AddNew();

myset.m_strCustID = _T("MSFT");

myset.m_strCustName = _T("Microsoft");

myset.Update();

Esempio 2 : uso solo dell'associazione dinamica

(presuppone l'uso della CDaoRecordset classe , rse è già aperto)

// 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();

Esempio 3 : uso di DAO Record Field Exchange e associazione dinamica

(presuppone l'esplorazione dei dati dei dipendenti con CDaoRecordsetla classe empderivata da )

// 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);

Funzionamento di DFX

Il meccanismo DFX funziona in modo simile al meccanismo RFX (Record Field Exchange) usato dalle classi ODBC MFC. I principi di DFX e RFX sono gli stessi, ma esistono numerose differenze interne. La progettazione delle funzioni DFX era tale che praticamente tutto il codice è condiviso dalle singole routine DFX. Al livello più alto DFX esegue solo alcune operazioni.

  • DFX costruisce la clausola SQL edizione Standard LECT e la clausola SQL PARAMETERS, se necessario.

  • DFX costruisce la struttura di associazione usata dalla funzione di GetRows DAO (più avanti).

  • DFX gestisce il buffer di dati usato per rilevare i campi dirty (se viene usato il doppio buffering)

  • DFX gestisce le matrici di stato NULL e DIRTY e imposta i valori, se necessario, negli aggiornamenti.

Al centro del meccanismo DFX è la CDaoRecordset funzione della DoFieldExchange classe derivata. Questa funzione invia le chiamate alle singole funzioni DFX di un tipo di operazione appropriato. Prima di chiamare DoFieldExchange le funzioni MFC interne, impostare il tipo di operazione. L'elenco seguente mostra i vari tipi di operazione e una breve descrizione.

Operazione Descrizione
AddToParameterList Clausola PARAMETERS di compilazione
AddToSelectList Compila edizione Standard clausolaLECT
BindField Configura la struttura di associazione
BindParam Imposta i valori dei parametri
Fixup Imposta lo stato NULL
AllocCache Alloca la cache per il controllo dirty
StoreField Salva il record corrente nella cache
LoadField Ripristina la cache ai valori dei membri
FreeCache Libera cache
SetFieldNull Imposta lo stato e il valore del campo su NULL
MarkForAddNew Contrassegna i campi sporchi se non P edizione Standard UDO NULL
MarkForEdit Contrassegna i campi sporchi se non corrispondono alla cache
SetDirtyField Imposta i valori dei campi contrassegnati come dirty

Nella sezione successiva, ogni operazione verrà illustrata in modo più dettagliato per DFX_Text.

La funzionalità più importante da comprendere sul processo di scambio dei campi di record DAO è che usa la GetRows funzione dell'oggetto CDaoRecordset . La funzione DAO GetRows può funzionare in diversi modi. Questa nota tecnica descriverà GetRows brevemente come non rientra nell'ambito di questa nota tecnica. DAO GetRows può funzionare in diversi modi.

  • Può recuperare più record e più campi di dati contemporaneamente. Ciò consente un accesso più rapido ai dati con la complicazione di gestire una struttura di dati di grandi dimensioni e gli offset appropriati per ogni campo e per ogni record di dati nella struttura. MFC non sfrutta questo meccanismo di recupero di più record.

  • Un altro modo GetRows può funzionare è consentire ai programmatori di specificare gli indirizzi di associazione per i dati recuperati di ogni campo per un record di dati.

  • DAO eseguirà anche il "callback" nel chiamante per le colonne a lunghezza variabile per consentire al chiamante di allocare memoria. Questa seconda funzionalità offre il vantaggio di ridurre al minimo il numero di copie dei dati e di consentire l'archiviazione diretta dei dati in membri di una classe (la CDaoRecordset classe derivata). Questo secondo meccanismo è il metodo usato da MFC per l'associazione ai membri dati nelle CDaoRecordset classi derivate.

Operazioni della routine DFX personalizzata

È evidente da questa discussione che l'operazione più importante implementata in qualsiasi funzione DFX deve essere la possibilità di configurare le strutture di dati necessarie per chiamare GetRowscorrettamente . Esistono diverse altre operazioni che una funzione DFX deve supportare, ma non altrettanto importante o complessa quanto la preparazione corretta per la GetRows chiamata.

L'uso di DFX è descritto nella documentazione online. Essenzialmente, esistono due requisiti. Prima di tutto, i membri devono essere aggiunti alla CDaoRecordset classe derivata per ogni campo e parametro associato. A questo scopo, è necessario eseguire l'override CDaoRecordset::DoFieldExchange . Si noti che il tipo di dati del membro è importante. Deve corrispondere ai dati del campo nel database o almeno essere convertibile in tale tipo. Ad esempio, un campo numerico nel database, ad esempio un numero intero lungo, può essere sempre convertito in testo e associato a un CString membro, ma un campo di testo in un database potrebbe non essere necessariamente convertito in una rappresentazione numerica, ad esempio un numero intero lungo e associato a un membro long integer. DAO e il motore di database Microsoft Jet sono responsabili della conversione (anziché MFC).

Dettagli delle DFX_Text

Come accennato in precedenza, il modo migliore per spiegare il funzionamento di DFX consiste nell'usare un esempio. A questo scopo, esaminare gli elementi interni di DFX_Text dovrebbe funzionare abbastanza bene per fornire almeno una conoscenza di base di DFX.

  • AddToParameterList

    Questa operazione compila la clausola SQL PARAMETERS ("Parameters <param name>, <param type> ... ;") richiesta da Jet. Ogni parametro è denominato e tipizzato (come specificato nella chiamata RFX). Vedere la funzione della funzione CDaoFieldExchange::AppendParamType per visualizzare i nomi dei singoli tipi. Nel caso di DFX_Text, il tipo usato è text.

  • AddToSelectList

    Compila la clausola SQL edizione Standard LECT. Questo è piuttosto semplice perché il nome della colonna specificato dalla chiamata DFX viene semplicemente accodato ("SELECT <column name>, ...").

  • BindField

    La più complessa delle operazioni. Come accennato in precedenza, questa è la posizione in cui viene configurata la struttura di associazione DAO usata da GetRows . Come si può notare dal codice nei DFX_Text tipi di informazioni nella struttura, includere il tipo DAO usato (DAO_CHAR o DAO_WCHAR nel caso di DFX_Text). Inoltre, viene configurato anche il tipo di associazione utilizzata. In una sezione GetRows precedente è stato descritto solo brevemente, ma era sufficiente spiegare che il tipo di binding usato da MFC è sempre l'associazione di indirizzi diretti (DAOBINDING_DIRECT). Inoltre, per l'associazione di callback a lunghezza variabile , ad esempio DFX_Text, viene usata l'associazione di callback in modo che MFC possa controllare l'allocazione della memoria e specificare un indirizzo della lunghezza corretta. Ciò significa che MFC può sempre indicare a DAO "dove" inserire i dati, consentendo così il binding diretto alle variabili membro. Il resto della struttura di associazione viene compilato con elementi come l'indirizzo della funzione di callback di allocazione della memoria e il tipo di associazione di colonna (binding in base al nome della colonna).

  • BindParam

    Si tratta di un'operazione semplice che chiama SetParamValue con il valore del parametro specificato nel membro del parametro.

  • Fixup

    Compila lo stato NULL per ogni campo.

  • SetFieldNull

    Questa operazione contrassegna solo ogni stato di campo come NULL e imposta il valore della variabile membro su P edizione StandardUDO_NULL.

  • SetDirtyField

    Chiama SetFieldValue ogni campo contrassegnato come dirty.

Tutte le operazioni rimanenti gestiscono solo l'uso della cache dei dati. La cache dei dati è un buffer aggiuntivo dei dati nel record corrente usato per semplificare determinate operazioni. Ad esempio, i campi "dirty" possono essere rilevati automaticamente. Come descritto nella documentazione online, può essere disattivato completamente o a livello di campo. L'implementazione del buffer utilizza una mappa. Questa mappa viene usata per associare copie allocate dinamicamente dei dati con l'indirizzo del campo "associato" (o CDaoRecordset membro dati derivato).

  • AllocCache

    Alloca dinamicamente il valore del campo memorizzato nella cache e lo aggiunge alla mappa.

  • FreeCache

    Elimina il valore del campo memorizzato nella cache e lo rimuove dalla mappa.

  • StoreField

    Copia il valore del campo corrente nella cache dei dati.

  • LoadField

    Copia il valore memorizzato nella cache nel membro del campo.

  • MarkForAddNew

    Controlla se il valore del campo corrente è diverso da NULL e lo contrassegna sporco, se necessario.

  • MarkForEdit

    Confronta il valore del campo corrente con la cache dei dati e contrassegna dirty, se necessario.

Suggerimento

Modellare le routine DFX personalizzate nelle routine DFX esistenti per i tipi di dati standard.

Vedi anche

Note tecniche per numero
Note tecniche per categoria