Partager via


Classes de consommateur générées par l’Assistant

L’Assistant Consommateur OLE DB ATL n’est pas disponible dans Visual Studio 2019 et versions ultérieures. Vous pouvez toujours ajouter la fonctionnalité manuellement.

Quand vous utilisez l’Assistant Consommateur OLE DB ATL pour générer un consommateur, vous pouvez utiliser soit des modèles OLE DB, soit des attributs OLE DB. Dans les deux cas, l’Assistant génère une classe de commande et une classe d’enregistrement utilisateur. La classe de commande contient du code destiné à ouvrir la source de données et le rowset que vous avez spécifié dans l’Assistant. La classe d’enregistrement utilisateur contient un mappage de colonnes pour la table de base de données que vous avez sélectionnée. Cependant, le code généré est différent dans chaque cas :

  • Si vous sélectionnez un consommateur basé sur un modèle, l’Assistant génère une classe de commande et une classe d’enregistrement utilisateur. La classe de commande prend le nom que vous entrez dans la zone Classe de l’Assistant (par exemple, CProducts), tandis que la classe prend un nom sous la forme « NomClasseAccessor » (par exemple, CProductsAccessor). Les deux classes sont placées dans le fichier d’en-tête du consommateur.

  • Si vous sélectionnez un consommateur avec attributs, la classe d’enregistrement utilisateur prend un nom sous la forme « _NomClasseAccessor » avant d’être injectée. Autrement dit, vous pourrez afficher uniquement la classe de commande dans l’éditeur de texte. Vous pouvez afficher la classe d’enregistrement utilisateur uniquement en tant que code injecté. Pour plus d’informations sur l’affichage de code injecté, consultez Débogage de code injecté.

Les exemples suivants utilisent une classe de commande créée dans la table Products de la base de données Northwind pour illustrer le code de consommateur généré par l’Assistant pour la classe de commande et la classe d’enregistrement utilisateur.

Classes d’enregistrement utilisateur basées sur un modèle

Si vous créez un consommateur OLE DB à l’aide des modèles OLE DB (et non des attributs OLE DB), l’Assistant génère du code comme décrit dans cette section.

Membres de données de colonne

La première partie de la classe d’enregistrement utilisateur comprend les déclarations des membres de données et les membres de données d’état et de longueur pour chaque colonne liée aux données. Pour plus d’informations sur ces membres de données, consultez Membres de données d’état des champs dans les accesseurs générés par l’Assistant.

Remarque

Si vous modifiez la classe d’enregistrement utilisateur ou écrivez votre propre consommateur, les variables de données doivent précéder les variables d’état et de longueur.

Remarque

L’Assistant Consommateur OLE DB ATL utilise le type DB_NUMERIC pour lier les types de données numériques. Auparavant, il utilisait DBTYPE_VARNUMERIC (dont le format est décrit par le type DB_VARNUMERIC ; voir OLE DB.h). Si vous n’utilisez pas l’Assistant pour créer des consommateurs, il est recommandé d’utiliser DB_NUMERIC.

// Products.H : Declaration of the CProducts class

class CProductsAccessor
{
public:
   // Column data members:
   LONG m_ProductID;
   TCHAR m_ProductName[41];
   LONG m_SupplierID;
   LONG m_CategoryID;
   TCHAR m_QuantityPerUnit[21];
   CURRENCY m_UnitPrice;
   SHORT m_UnitsInStock;
   SHORT m_UnitsOnOrder;
   SHORT m_ReorderLevel;
   VARIANT_BOOL m_Discontinued;

   // Column status data members:
   DBSTATUS m_dwProductIDStatus;
   DBSTATUS m_dwProductNameStatus;
   DBSTATUS m_dwSupplierIDStatus;
   DBSTATUS m_dwCategoryIDStatus;
   DBSTATUS m_dwQuantityPerUnitStatus;
   DBSTATUS m_dwUnitPriceStatus;
   DBSTATUS m_dwUnitsInStockStatus;
   DBSTATUS m_dwUnitsOnOrderStatus;
   DBSTATUS m_dwReorderLevelStatus;
   DBSTATUS m_dwDiscontinuedStatus;

   // Column length data members:
   DBLENGTH m_dwProductIDLength;
   DBLENGTH m_dwProductNameLength;
   DBLENGTH m_dwSupplierIDLength;
   DBLENGTH m_dwCategoryIDLength;
   DBLENGTH m_dwQuantityPerUnitLength;
   DBLENGTH m_dwUnitPriceLength;
   DBLENGTH m_dwUnitsInStockLength;
   DBLENGTH m_dwUnitsOnOrderLength;
   DBLENGTH m_dwReorderLevelLength;
   DBLENGTH m_dwDiscontinuedLength;

Propriétés du rowset

Ensuite, l’Assistant définit les propriétés du rowset. Si vous avez sélectionné Modifier, Insérerou Supprimer dans l’Assistant Consommateur OLE DB ATL, les propriétés appropriées sont définies ici (DBPROP_IRowsetChange est toujours défini, puis une ou plusieurs propriétés parmi DBPROPVAL_UP_CHANGE, DBPROPVAL_UP_INSERT et/ou DBPROPVAL_UP_DELETE, respectivement).

void GetRowsetProperties(CDBPropSet* pPropSet)
{
   pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
   pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
   pPropSet->AddProperty(DBPROP_IRowsetChange, true, DBPROPOPTIONS_OPTIONAL);
   pPropSet->AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE);
}

Classe de commande ou de table

Si vous spécifiez une classe de commande, l’Assistant déclare la classe de commande ; pour le code basé sur un modèle, la commande se présente comme suit :

DEFINE_COMMAND_EX(CProductsAccessor, L" \
SELECT \
   ProductID, \
   ProductName, \
   SupplierID, \
   CategoryID, \
   QuantityPerUnit, \
   UnitPrice, \
   UnitsInStock, \
   UnitsOnOrder, \
   ReorderLevel, \
   Discontinued \
   FROM dbo.Products")

Mappage de colonnes

L’Assistant génère ensuite les liaisons de colonnes ou le mappage de colonnes. Pour corriger plusieurs problèmes rencontrés avec certains fournisseurs, le code ci-dessous peut lier les colonnes dans un ordre différent de celui indiqué par le fournisseur.

   BEGIN_COLUMN_MAP(CProductsAccessor)
      COLUMN_ENTRY_LENGTH_STATUS(1, m_ProductID, m_dwProductIDLength, m_dwProductIDStatus)
      COLUMN_ENTRY_LENGTH_STATUS(2, m_ProductName, m_dwProductNameLength, m_dwProductNameStatus)
      COLUMN_ENTRY_LENGTH_STATUS(3, m_SupplierID, m_dwSupplierIDLength, m_dwSupplierIDStatus)
      COLUMN_ENTRY_LENGTH_STATUS(4, m_CategoryID, m_dwCategoryIDLength, m_dwCategoryIDStatus)
      COLUMN_ENTRY_LENGTH_STATUS(5, m_QuantityPerUnit, m_dwQuantityPerUnitLength, m_dwQuantityPerUnitStatus)
      _COLUMN_ENTRY_CODE(6, DBTYPE_CY, _SIZE_TYPE(m_UnitPrice), 0, 0, offsetbuf(m_UnitPrice), offsetbuf(m_dwUnitPriceLength), offsetbuf(m_dwUnitPriceStatus))
      COLUMN_ENTRY_LENGTH_STATUS(7, m_UnitsInStock, m_dwUnitsInStockLength, m_dwUnitsInStockStatus)
      COLUMN_ENTRY_LENGTH_STATUS(8, m_UnitsOnOrder, m_dwUnitsOnOrderLength, m_dwUnitsOnOrderStatus)
      COLUMN_ENTRY_LENGTH_STATUS(9, m_ReorderLevel, m_dwReorderLevelLength, m_dwReorderLevelStatus)
      _COLUMN_ENTRY_CODE(10, DBTYPE_BOOL, _SIZE_TYPE(m_Discontinued), 0, 0, offsetbuf(m_Discontinued), offsetbuf(m_dwDiscontinuedLength), offsetbuf(m_dwDiscontinuedStatus))
   END_COLUMN_MAP()
};

Déclaration de classe

Enfin, l’Assistant génère une déclaration de classe de commande semblable à la suivante :

class CProducts : public CCommand<CAccessor<CProductsAccessor>>

Classes d'enregistrement utilisateur injectées par les attributs

Si vous créez un consommateur OLE DB à l’aide des attributs de base de données (db_command ou db_table), les attributs injectent une classe d’enregistrement utilisateur avec le nom de la forme « _ClassNameAccessor ». Par exemple, si vous avez nommé votre classe COrdersde commande, la classe d’enregistrement utilisateur sera _COrdersAccessor. Bien que la classe d’enregistrement utilisateur s’affiche dans Affichage de classes, double-cliquer dessus vous redirige vers la classe de commande ou de table dans le fichier d’en-tête. Dans ce cas, vous ne pouvez voir la déclaration réelle de la classe d’enregistrement utilisateur qu’en affichant le code injecté par les attributs.

Vous pouvez rencontrer des complications si vous ajoutez ou substituez des méthodes dans des consommateurs avec attributs. Par exemple, vous pouvez décider d’ajouter un constructeur _COrdersAccessor à la déclaration COrders . Or, en réalité, le constructeur est ajouté à la classe COrdersAccessor injectée. Un constructeur de ce type peut initialiser les colonnes/paramètres, mais vous ne pouvez pas créer un constructeur de copie de cette façon, car il ne peut pas instancier directement l’objet COrdersAccessor. Si vous avez besoin d’un constructeur (ou autre méthode) directement dans la classe COrders, il est recommandé de définir une nouvelle classe dérivant de COrders et d’y ajouter les méthodes nécessaires.

Dans l’exemple suivant, l’Assistant génère une déclaration pour la classe COrders, mais la classe d’enregistrement utilisateur COrdersAccessor n’apparaît pas, car elle est injectée par les attributs.

#define _ATL_ATTRIBUTES
#include <atlbase.h>
#include <atldbcli.h>
[
   db_source(L"your connection string"),
   db_command(L"Select ShipName from Orders;")
]
class COrders
{
public:

   // COrders()            // incorrect constructor name
   _COrdersAccessor()      // correct constructor name
   {
   }
      [db_column(1) ] TCHAR m_ShipName[41];
   };

La déclaration de classe de commande injectée se présente comme ceci :

class CProducts : public CCommand<CAccessor<_CProductsAccessor>>

Le code injecté est pour l’essentiel identique ou similaire à la version basée sur un modèle. Les principales différences résident dans les méthodes injectées, qui sont décrites dans Méthodes générées par l’Assistant Consommateur.

Pour plus d’informations sur l’affichage de code injecté, consultez Débogage de code injecté.

Voir aussi

Création d’un consommateur OLE DB en utilisant l’Assistant