Condividi tramite


TN053: routine DFX personalizzate per classi di database DAO

Annotazioni

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.

Annotazioni

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

Esempio 1 — Uso solo dello 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 di CDaoRecordsetclasse, rs ed è 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 la consultazione dei dati dei dipendenti utilizzando la classe derivata da CDaoRecordsetemp)

// 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 SELECT 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 Costruisce la clausola PARAMETERS
AddToSelectList Costruisce la clausola SELECT
BindField Configura la struttura di vincolo
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 i valori della cache dei membri
FreeCache Libera la cache
SetFieldNull Imposta lo stato e il valore del campo su NULL
MarkForAddNew Contrassegna i campi sporchi se non PSEUDO 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.

L'aspetto più importante da comprendere nel processo di scambio dei campi di record DAO è che utilizza la funzione GetRows dell'oggetto CDaoRecordset. La funzione DAO GetRows può funzionare in diversi modi. Questa nota tecnica descriverà solo brevemente GetRows, poiché è al di fuori dell'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 un "callback" al chiamante per consentirgli di allocare memoria per colonne a lunghezza variabile. 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. Successivamente, CDaoRecordset::DoFieldExchange dovrebbe essere sovrascritto. Si noti che il tipo di dato del membro è importante. Deve corrispondere ai dati del campo nel database o almeno essere convertibile in tale tipo. Ad esempio, un campo numerico in un database, come un numero intero lungo, può sempre essere convertito in testo e associato a un membro CString, mentre un campo di testo in un database potrebbe non essere necessariamente convertito in una rappresentazione numerica, come un numero intero lungo, e associato a un membro numero intero lungo. DAO e il motore di database Microsoft Jet sono responsabili della conversione (anziché MFC).

Dettagli di 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). Consultare la funzione CDaoFieldExchange::AppendParamType per visualizzare i nomi dei singoli tipi. Nel caso di DFX_Text, il tipo usato è text.

  • AddToSelectList

    Compila la clausola SQL SELECT . 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ò vedere nel codice su DFX_Text, i tipi di informazioni nella struttura includono 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 associazione usato da MFC è sempre l'associazione di indirizzi diretti (DAOBINDING_DIRECT). Inoltre, per l'associazione di colonne a lunghezza variabile (ad esempio DFX_Text), viene utilizzata 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 nella proprietà dei parametri.

  • 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 PSEUDO_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 corrispondere le copie dei dati allocate dinamicamente con l'indirizzo del campo "associato" (o CDaoRecordset membro dei 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.

Vedere anche

Note tecniche per numero
Note tecniche per categoria