Udostępnij za pośrednictwem


Klasy konsumentów generowane przez kreatora

Kreator konsumenta OLE DB ATL nie jest dostępny w programie Visual Studio 2019 i nowszych wersjach. Nadal można dodać funkcjonalność ręcznie.

Jeśli do wygenerowania użytkownika używasz Kreatora konsumenta OLE DB ATL, możesz użyć szablonów OLE DB lub atrybutów OLE DB. W obu przypadkach kreator generuje klasę poleceń i klasę rekordów użytkownika. Klasa poleceń zawiera kod umożliwiający otwarcie źródła danych i zestawu wierszy określonego w kreatorze. Klasa rekordów użytkownika zawiera mapę kolumn dla wybranej tabeli bazy danych. Jednak wygenerowany kod różni się w każdym przypadku:

  • Jeśli wybierzesz szablonowego konsumenta, kreator wygeneruje klasę poleceń i klasę rekordów użytkownika. Klasa poleceń będzie miała nazwę wprowadzoną w polu Klasa w kreatorze (na przykład CProducts), a klasa rekordów użytkownika będzie miała nazwę formularza "KlasaNazwadostępu" (na przykład CProductsAccessor). Obie klasy są umieszczane w pliku nagłówkowym odbiorcy.

  • Jeśli wybierzesz przypisanego konsumenta, klasa rekordów użytkownika będzie miała nazwę formularza "_ClassNameAccessor" i zostanie wstrzyknięta. Oznacza to, że będzie można wyświetlić tylko klasę poleceń w edytorze tekstów; Klasę rekordów użytkownika można wyświetlić tylko jako kod wstrzyknięty. Aby uzyskać informacje na temat wyświetlania wprowadzonego kodu, zobacz Debugowanie wprowadzonego kodu.

W poniższych przykładach użyto klasy poleceń utworzonej Northwind w Products tabeli bazy danych, aby zademonstrować kod odbiorcy wygenerowany przez kreatora dla klasy poleceń i klasy rekordów użytkownika.

Klasy rekordów użytkownika szablonu

Jeśli tworzysz użytkownika OLE DB przy użyciu szablonów OLE DB (a nie atrybutów OLE DB), kreator generuje kod zgodnie z opisem w tej sekcji.

Składowe danych kolumn

Pierwsza część klasy rekordów użytkownika zawiera deklaracje składowych danych oraz składowe stanu i długości danych dla każdej kolumny powiązanej z danymi. Aby uzyskać informacje o tych elementach członkowskich danych, zobacz Składowe danych stanu pola w metodach dostępu generowanych przez kreatora.

Uwaga

Jeśli zmodyfikujesz klasę rekordów użytkownika lub zapiszesz własnego konsumenta, zmienne danych muszą znajdować się przed zmiennymi stanu i długości.

Uwaga

Kreator konsumenta OLE DB ATL używa DB_NUMERIC typu do powiązania typów danych liczbowych. Wcześniej używany DBTYPE_VARNUMERIC (format, którego format jest opisany przez DB_VARNUMERIC typ; zobacz Oledb.h). Jeśli nie używasz kreatora do tworzenia użytkowników, zaleca się użycie polecenia 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;

Właściwości zestawu wierszy

Następnie kreator ustawia właściwości zestawu wierszy. W przypadku wybrania opcji Zmień, Wstaw lub Usuń w Kreatorze konsumenta OLE DB ATL odpowiednie właściwości są ustawione w tym miejscu (DBPROP_IRowsetChange jest zawsze ustawiana, a następnie co najmniej jedna DBPROPVAL_UP_CHANGE, DBPROPVAL_UP_INSERT i/lub DBPROPVAL_UP_DELETE, odpowiednio).

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

Command or Table Class

Jeśli określisz klasę poleceń, kreator deklaruje klasę poleceń; w przypadku kodu szablonu polecenie wygląda następująco:

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

Mapa kolumn

Następnie kreator generuje powiązania kolumn lub mapę kolumn. Aby rozwiązać kilka problemów z niektórymi dostawcami, poniższy kod może powiązać kolumny w innej kolejności niż zgłoszone przez dostawcę.

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

Deklaracja klasy

Na koniec kreator generuje deklarację klasy poleceń, taką jak:

class CProducts : public CCommand<CAccessor<CProductsAccessor>>

Klasy rekordów użytkownika wstrzykiwane przez atrybuty

Jeśli tworzysz użytkownika OLE DB przy użyciu atrybutów bazy danych (db_command lub db_table), atrybuty wprowadzają klasę rekordów użytkownika o nazwie formularza "_ClassNameAccessor". Jeśli na przykład nazwano klasę COrderspoleceń , klasa rekordu użytkownika będzie mieć wartość _COrdersAccessor. Mimo że klasa rekordów użytkownika jest wyświetlana w widoku klasy, dwukrotne kliknięcie go powoduje przejście do polecenia lub klasy tabeli w pliku nagłówka. W takich przypadkach można wyświetlić tylko rzeczywistą deklarację klasy rekordów użytkownika, wyświetlając kod wstrzykiwany atrybutem.

Mogą wystąpić potencjalne komplikacje, jeśli dodasz lub przesłonisz metody dla użytkowników przypisanych. Można na przykład dodać _COrdersAccessor konstruktor do COrders deklaracji, ale należy pamiętać, że w rzeczywistości dodaje konstruktor do wstrzykiwanej COrdersAccessor klasy. Taki konstruktor może zainicjować kolumny/parametry, ale nie można w ten sposób utworzyć konstruktora kopiowania, ponieważ nie może bezpośrednio utworzyć COrdersAccessor wystąpienia obiektu. Jeśli potrzebujesz konstruktora (lub innej metody) bezpośrednio w COrders klasie, zaleca się zdefiniowanie nowej klasy pochodnej i COrders dodanie niezbędnych metod.

W poniższym przykładzie kreator generuje deklarację dla klasy COrders, ale klasa COrdersAccessor rekordów użytkownika nie jest wyświetlana, ponieważ atrybuty go wstrzykiwają.

#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];
   };

Wstrzyknięta deklaracja klasy poleceń wygląda następująco:

class CProducts : public CCommand<CAccessor<_CProductsAccessor>>

Większość wprowadzonego kodu jest taka sama jak lub podobna do wersji szablonu. Główne różnice dotyczą metod wstrzykiwanych, które opisano w temacie Metody generowane przez kreatora odbiorców.

Aby uzyskać informacje na temat wyświetlania wprowadzonego kodu, zobacz Debugowanie wprowadzonego kodu.

Zobacz też

Tworzenie konsumenta OLE DB przy użyciu kreatora