Condividi tramite


Classi generate mediante la Creazione guidata consumer

Se si decide di generare un consumer mediante la Creazione guidata consumer OLE DB ATL, si può scegliere di utilizzare i modelli OLE DB oppure gli attributi OLE DB. In entrambi i casi, verrà generata una classe di comando e una classe di record utente. La classe di comando contiene codice che consente di aprire l'origine dati e il rowset specificati nella creazione guidata. La classe di record utente contiene una mappa delle colonne della tabella di database selezionata. Tuttavia, il codice generato in ciascuno dei casi sarà differente:

  • Se si seleziona un consumer basato su modelli, verrà generata una classe di comando e una classe di record utente. Il nome della classe di comando sarà quello immesso nella casella Classe nell'ambito della procedura guidata (ad esempio, CProducts), quello della classe di record utente avrà il formato "NomeClasseAccessor" (ad esempio, CProductsAccessor). Entrambe le classi verranno inserite nel file di intestazione del consumer.

  • Se si seleziona un consumer basato su attributi, la classe di record utente assumerà un nome nel formato "_NomeClasseAccessor" e verrà inserita. Pertanto, nell'editor di testo sarà possibile visualizzare solo la classe di comando. La classe di record utente potrà essere visualizzata solo come codice inserito. Per informazioni sulla visualizzazione di codice inserito, vedere Debug di codice inserito.

Negli esempi che seguono viene utilizzata una classe di comando creata nella tabella Products del database Northwind per illustrare il codice del consumer generato mediante procedura guidata per la classe di comando e la classe di record utente:

Classi di record utente basate su modelli

Se si crea un consumer OLE DB sulla base dei modelli OLE DB anziché degli attributi OLE DB, il codice verrà generato secondo le modalità descritte in questa sezione.

Membri dati delle colonne

La prima parte della classe di record utente include le dichiarazioni dei membri dati e i membri dati di stato e di lunghezza per ciascuna colonna associata a dati. Per informazioni su questi membri dati, vedere Membri dati di stato dei campi in funzioni di accesso generate dalla creazione guidata.

Nota

Se si modifica la classe di record utente o si crea un consumer personalizzato, le variabili dei dati devono essere specificate prima delle variabili di stato e di lunghezza.

Nota

La Creazione guidata consumer OLE DB ATL utilizza il tipo DB_NUMERIC per associare tipi di dati numerici. In precedenza veniva utilizzato DBTYPE_VARNUMERIC. Per informazioni sul formato descritto dal tipo DB_VARNUMERIC, vedere Oledb.h. Se non si utilizza la procedura guidata per creare i consumer, si consiglia di utilizzare 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;

Proprietà del rowset

A questo punto, vengono impostate le proprietà del rowset. Se si seleziona Cambia, Inserisci o Elimina nella Creazione guidata consumer OLE DB ATL, verranno impostate le opportune proprietà: DBPROP_IRowsetChange, in tutti e tre i casi, e almeno una, rispettivamente, tra le proprietà DBPROPVAL_UP_CHANGE, DBPROPVAL_UP_INSERT e/o DBPROPVAL_UP_DELETE.

   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 di comando o di tabella

Se si specifica una classe di comando, questa verrà automaticamente dichiarata. Il comando per un codice basato su modelli, ad esempio, sarà definito nel modo seguente:

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

Mappa delle colonne

A questo punto vengono automaticamente generate le associazioni delle colonne o mappa della colonne. Per risolvere vari problemi relativi ad alcuni provider, mediante il codice seguente è possibile associare le colonne in modo differente rispetto a quello indicato dal provider:

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

Dichiarazione di classe

Infine, verrà generata la dichiarazione di una classe di comando quale la seguente:

class CProducts : public CCommand<CAccessor<CProductsAccessor> >

Classi di record utente inserite dagli attributi

Se si crea un consumer OLE DB utilizzando gli attributi del database db_command o db_table, in base a questi verrà inserita una classe di record utente con un nome nel formato "_NomeClasseAccessor." Se, ad esempio, la classe di comando è stata denominata COrders, la classe di record utente sarà _COrdersAccessor. Sebbene la classe di record utente venga visualizzata in Visualizzazione classi, facendo doppio clic su di essa è anche possibile passare alla classe di comando o di tabella nel file di intestazione. In questi casi, la visualizzazione del codice inserito dagli attributi consente solo di visualizzare la dichiarazione effettiva della classe di record utente.

È possibile che si verifichino problemi se si aggiungono metodi o si eseguono override dei metodi in consumer con attributi. Aggiungendo, ad esempio, un costruttore di _COrdersAccessor alla dichiarazione di COrders, in realtà verrebbe aggiunto un costruttore alla classe COrdersAccessor inserita. In questo modo tale costruttore potrebbe inizializzare le colonne o i parametri, ma non sarebbe in grado di creare un costruttore di copia, poiché non potrebbe creare in modo diretto istanze dell'oggetto COrdersAccessor. Per disporre di un costruttore o di un metodo direttamente nella classe COrders, è consigliabile definire una nuova classe derivante da COrders e aggiungere ad essa i metodi necessari.

Nell'esempio seguente viene generata una dichiarazione per la classe COrders, ma non vi compare la classe di record utente COrdersAccessor, che viene inserita dagli attributi.

#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 dichiarazione della classe di comando inserita sarà analoga alla seguente:

class CProducts : public CCommand<CAccessor<_CProductsAccessor> >

La maggior parte del codice inserito è identica o simile alla versione basata sui modelli. Le principali differenze riguardano i metodi inseriti, che sono descritti in Metodi generati mediante la Creazione guidata consumer.

Per informazioni sulla visualizzazione di codice inserito, vedere Debug di codice inserito.

Vedere anche

Concetti

Creazione di un consumer OLE DB mediante procedura guidata