TN053 : personnaliser les routines DFX pour les classes de base de données DAO
Remarque
DAO est utilisé avec les bases de données Access et est pris en charge via Bureau 2013. DAO 3.6 est la version finale, et elle est considérée comme obsolète. L’environnement et les Assistants Visual C++ ne prennent pas en charge DAO (bien que les classes DAO soient incluses et que vous pouvez toujours les utiliser). Microsoft vous recommande d’utiliser des modèles OLE DB ou ODBC et MFC pour de nouveaux projets. Vous devez uniquement utiliser DAO pour gérer les applications existantes.
Cette note technique décrit le mécanisme d’échange de champs d’enregistrement DAO (DFX). Pour mieux comprendre ce qui se passe dans les routines DFX, la DFX_Text
fonction sera expliquée en détail comme exemple. En guise de source supplémentaire d’informations à cette note technique, vous pouvez examiner le code pour les autres fonctions DFX individuelles. Vous n’aurez probablement pas besoin d’une routine DFX personnalisée aussi souvent que vous pourriez avoir besoin d’une routine RFX personnalisée (utilisée avec des classes de base de données ODBC).
Cette note technique contient :
Vue d’ensemble de DFX
Exemples utilisant l’échange de champs d’enregistrement DAO et la liaison dynamique
Vue d’ensemble de DFX
Le mécanisme d’échange de champs d’enregistrement DAO (DFX) est utilisé pour simplifier la procédure de récupération et de mise à jour des données lors de l’utilisation de la CDaoRecordset
classe. Le processus est simplifié à l’aide des membres de données de la CDaoRecordset
classe. En dérivant de , vous pouvez ajouter des membres de CDaoRecordset
données à la classe dérivée représentant chaque champ dans une table ou une requête. Ce mécanisme de « liaison statique » est simple, mais il peut ne pas s’agir de la méthode d’extraction/mise à jour des données de choix pour toutes les applications. DFX récupère chaque champ lié chaque fois que l’enregistrement actif est modifié. Si vous développez une application sensible aux performances qui ne nécessite pas d’extraction de chaque champ lorsque la devise est modifiée, la « liaison dynamique » via CDaoRecordset::GetFieldValue
et CDaoRecordset::SetFieldValue
peut être la méthode d’accès aux données de choix.
Remarque
Les liaisons DFX et dynamiques ne s’excluent pas mutuellement, de sorte qu’une utilisation hybride de liaison statique et dynamique peut être utilisée.
Exemple 1 : utilisation d’un échange de champs d’enregistrement DAO uniquement
(suppose : CDaoRecordset
classe CMySet
dérivée déjà ouverte)
// Add a new record to the customers table
myset.AddNew();
myset.m_strCustID = _T("MSFT");
myset.m_strCustName = _T("Microsoft");
myset.Update();
Exemple 2 : utilisation de liaison dynamique uniquement
(suppose que l’utilisation de CDaoRecordset
la classe, rs
et qu’elle est déjà ouverte)
// 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();
Exemple 3 : utilisation d’un échange de champs d’enregistrement DAO et d’une liaison dynamique
(suppose que l’exploration des données des employés avec CDaoRecordset
la classe emp
dérivée )
// 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);
Fonctionnement de DFX
Le mécanisme DFX fonctionne de la même manière que le mécanisme d’échange de champs d’enregistrement (RFX) utilisé par les classes ODBC MFC. Les principes de DFX et RFX sont les mêmes, mais il existe de nombreuses différences internes. La conception des fonctions DFX était telle que pratiquement tout le code est partagé par les routines DFX individuelles. Au niveau le plus élevé, DFX ne fait que quelques choses.
DFX construit la clause SQL SELECT et la clause SQL PARAMETERS si nécessaire.
DFX construit la structure de liaison utilisée par la fonction de DAO
GetRows
(plus loin).DFX gère la mémoire tampon de données utilisée pour détecter les champs sale (si la double mise en mémoire tampon est utilisée)
DFX gère les tableaux d’état NULL et DIRTY et définit les valeurs si nécessaire sur les mises à jour.
Au cœur du mécanisme DFX est la fonction de DoFieldExchange
la CDaoRecordset
classe dérivée. Cette fonction répartit les appels aux fonctions DFX individuelles d’un type d’opération approprié. Avant d’appeler DoFieldExchange
les fonctions MFC internes, définissez le type d’opération. La liste suivante présente les différents types d’opérations et une brève description.
Operation | Description |
---|---|
AddToParameterList |
Builds PARAMETERS, clause |
AddToSelectList |
Builds SELECT, clause |
BindField |
Configurer la structure de liaison |
BindParam |
Définit les valeurs des paramètres |
Fixup |
Définit l’état NULL |
AllocCache |
Alloue le cache pour sale case activée |
StoreField |
Enregistre l’enregistrement actif dans le cache |
LoadField |
Restaure le cache sur les valeurs des membres |
FreeCache |
Cache gratuit |
SetFieldNull |
Définit l’état du champ et la valeur NULL |
MarkForAddNew |
Marque les champs sale s’il n’est pas PSEUDO NULL |
MarkForEdit |
Marque les champs sale s’ils ne correspondent pas au cache |
SetDirtyField |
Définit les valeurs de champ marquées comme sale |
Dans la section suivante, chaque opération sera expliquée plus en détail pour DFX_Text
.
La fonctionnalité la plus importante à comprendre sur le processus d’échange de champs d’enregistrement DAO est qu’elle utilise la GetRows
fonction de l’objet CDaoRecordset
. La fonction DAO GetRows
peut fonctionner de plusieurs façons. Cette note technique ne décrit GetRows
brièvement qu’en dehors de la portée de cette note technique.
DAO GetRows
peut travailler de plusieurs façons.
Il peut extraire plusieurs enregistrements et plusieurs champs de données à la fois. Cela permet un accès plus rapide aux données avec la complication du traitement d’une structure de données volumineuse et des décalages appropriés pour chaque champ et pour chaque enregistrement de données dans la structure. MFC ne tire pas parti de ce mécanisme d’extraction d’enregistrements multiples.
Une autre façon
GetRows
de fonctionner consiste à permettre aux programmeurs de spécifier des adresses de liaison pour les données récupérées de chaque champ pour un enregistrement de données.DAO va également « rappeler » dans l’appelant pour les colonnes de longueur variable afin de permettre à l’appelant d’allouer de la mémoire. Cette deuxième fonctionnalité présente l’avantage de réduire le nombre de copies de données, ainsi que de permettre un stockage direct de données dans des membres d’une classe (la
CDaoRecordset
classe dérivée). Ce deuxième mécanisme est la méthode MFC utilisée pour lier des membres de données dansCDaoRecordset
des classes dérivées.
Ce que fait votre routine DFX personnalisée
Il ressort de cette discussion que l’opération la plus importante implémentée dans n’importe quelle fonction DFX doit être la possibilité de configurer les structures de données requises pour appeler GetRows
avec succès . Il existe un certain nombre d’autres opérations qu’une fonction DFX doit également prendre en charge, mais aucune aussi importante ou complexe que la préparation correcte de l’appel GetRows
.
L’utilisation de DFX est décrite dans la documentation en ligne. Essentiellement, il existe deux exigences. Tout d’abord, les membres doivent être ajoutés à la CDaoRecordset
classe dérivée pour chaque champ et paramètre lié. Après cela CDaoRecordset::DoFieldExchange
, vous devez remplacer. Notez que le type de données du membre est important. Il doit correspondre aux données du champ de la base de données ou au moins être convertibles en ce type. Par exemple, un champ numérique dans une base de données, tel qu’un entier long, peut toujours être converti en texte et lié à un CString
membre, mais un champ de texte d’une base de données peut ne pas nécessairement être converti en représentation numérique, comme un entier long et lié à un membre entier long. DAO et le moteur de base de données Microsoft Jet sont responsables de la conversion (plutôt que MFC).
Détails de DFX_Text
Comme mentionné précédemment, la meilleure façon d’expliquer le fonctionnement de DFX consiste à utiliser un exemple. À cet effet, les internes de DFX_Text
devraient fonctionner très bien pour vous aider à fournir au moins une compréhension de base de DFX.
AddToParameterList
Cette opération génère la clause SQL PARAMETERS («
Parameters <param name>, <param type> ... ;
») requise par Jet. Chaque paramètre est nommé et typé (tel que spécifié dans l’appel RFX). Consultez la fonction de fonctionCDaoFieldExchange::AppendParamType
pour afficher les noms des types individuels. Dans le cas deDFX_Text
, le type utilisé est texte.AddToSelectList
Génère la clause SQL SELECT . Cela est assez simple, car le nom de colonne spécifié par l’appel DFX est simplement ajouté ( »
SELECT <column name>, ...
« ).BindField
Le plus complexe des opérations. Comme mentionné précédemment, il s’agit de l’emplacement où la structure de liaison DAO utilisée par
GetRows
est configurée. Comme vous pouvez le voir à partir du code dansDFX_Text
les types d’informations de la structure incluent le type DAO utilisé (DAO_CHAR ou DAO_WCHAR dans le cas deDFX_Text
). En outre, le type de liaison utilisé est également configuré. Dans une sectionGetRows
antérieure, elle n’a été décrite que brièvement, mais il suffit d’expliquer que le type de liaison utilisé par MFC est toujours une liaison d’adresse directe (DAOBINDING_DIRECT). En plus de la liaison de colonne de longueur variable (commeDFX_Text
) la liaison de rappel est utilisée afin que MFC puisse contrôler l’allocation de mémoire et spécifier une adresse de la longueur correcte. Cela signifie que MFC peut toujours indiquer à DAO « où » placer les données, ce qui permet de lier directement aux variables membres. Le reste de la structure de liaison est rempli avec des éléments tels que l’adresse de la fonction de rappel d’allocation de mémoire et le type de liaison de colonne (liaison par nom de colonne).BindParam
Il s’agit d’une opération simple qui appelle
SetParamValue
avec la valeur de paramètre spécifiée dans votre membre de paramètre.Fixup
Renseigne l’état NULL de chaque champ.
SetFieldNull
Cette opération marque uniquement chaque état de champ comme NULL et définit la valeur de la variable membre sur PSEUDO_NULL.
SetDirtyField
Appelle
SetFieldValue
chaque champ marqué sale.
Toutes les opérations restantes traitent uniquement de l’utilisation du cache de données. Le cache de données est une mémoire tampon supplémentaire des données dans l’enregistrement actif qui est utilisée pour simplifier certaines choses. Par exemple, les champs « sale » peuvent être détectés automatiquement. Comme décrit dans la documentation en ligne, il peut être désactivé complètement ou au niveau du champ. L’implémentation de la mémoire tampon utilise une carte. Cette carte est utilisée pour faire correspondre des copies allouées dynamiquement des données avec l’adresse du champ « lié » (ou CDaoRecordset
membre de données dérivé).
AllocCache
Alloue dynamiquement la valeur du champ mis en cache et l’ajoute à la carte.
FreeCache
Supprime la valeur du champ mis en cache et la supprime de la carte.
StoreField
Copie la valeur de champ actuelle dans le cache de données.
LoadField
Copie la valeur mise en cache dans le membre de champ.
MarkForAddNew
Vérifie si la valeur de champ actuelle n’est pas NULL et la marque sale si nécessaire.
MarkForEdit
Compare la valeur de champ actuelle avec le cache de données et les marques sale si nécessaire.
Conseil
Modélisez vos routines DFX personnalisées sur les routines DFX existantes pour les types de données standard.