Поделиться через


Классы, создаваемые мастером объекта-получателя

Мастер объекта-получателя ATL OLE DB недоступен в Visual Studio 2019 и более поздних версиях. Эту функцию все еще можно добавить вручную.

При создании потребителя с помощью мастера потребителя ATL OLE DB вы можете выбрать использование шаблонов OLE DB или атрибутов OLE DB. В обоих случаях мастер создает класс команд и класс записей пользователя. В классе команд содержится код для открытия источника данных и набора строк, указанных в мастере. Класс записей пользователя содержит сопоставление столбцов для выбранной таблицы базы данных. Однако созданный код в каждом случае отличается.

  • Если вы выбираете потребителя на основе шаблонов, мастер создает класс команд и класс записей пользователя. Класс команд будет иметь имя, введенное в поле класс в мастере (например, CProducts), а класс записей пользователя будет иметь имя в формате "имя_классаметод_доступа" (например, CProductsAccessor). Оба класса находятся в файле заголовка потребителя.

  • При выборе потребителя на основе атрибутов класс записей пользователя будет иметь имя в форме "_ИмяКлассаAccessor" и будет внедренным. То есть в текстовом редакторе вы сможете просматривать только класс команд. Класс записей пользователя вы сможете просматривать только как внедренный код. Сведения о просмотре внедренного кода см. в разделе Отладка внедренного кода.

В следующих примерах с помощью класса команд, созданного в таблице Products базы данных Northwind, демонстрируется код пользователя, создаваемого мастером потребителя для класса команд и класса записей.

Классы записей пользователя на основе шаблонов

При создании потребителя OLE DB с помощью шаблонов OLE DB (а не атрибутов OLE DB) мастер создает код, как описано в этом разделе.

Элементы данных столбцов

Первая часть класса записей пользователя включает объявления элементов данных и элементы данных состояния и длины для каждого столбца с привязкой к данным. Сведения об этих элементах данных см. в разделе Элементы данных состояния поля в создаваемых мастером методах доступа.

Примечание.

Если вы изменяете класс записей пользователя или создаете собственного потребителя, переменные данных должны находиться перед переменными состояния и длины.

Примечание.

Мастер потребителя ATL OLE DB использует тип DB_NUMERIC для привязки числовых типов данных. Ранее он использовал DBTYPE_VARNUMERIC (формат которого описывался типом DB_VARNUMERIC; см. Oledb.h). Если потребители создаются без помощи мастера, рекомендуется использовать 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;

Свойства набора строк

Далее мастер задает свойства набора строк. Если в мастере потребителя ATL OLE DB вы выбрали Изменить, Вставитьили Удалить , здесь задаются соответствующие свойства (свойство DBPROP_IRowsetChange всегда задается, а затем одно или несколько свойств DBPROPVAL_UP_CHANGE, DBPROPVAL_UP_INSERT или 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);
}

Класс команд или таблиц

Если вы указали класс команд, мастер объявляет класс команд; для кода на основе шаблонов команда выглядит следующим образом:

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

Сопоставление столбцов

Затем мастер создает привязки столбцов или сопоставление столбцов. Для устранения некоторых проблем с поставщиками следующий код может привязывать столбцы в порядке, отличном от сообщаемого поставщиком.

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

Объявление класса

Наконец, мастер создает объявление класса команд, например следующим образом:

class CProducts : public CCommand<CAccessor<CProductsAccessor>>

Классы записей пользователя, внедряемые атрибутами

При создании потребителя OLE DB с помощью атрибутов базы данных (db_command или db_table), атрибуты внедряют класс записи пользователя с именем формы "_ClassNameAccessor". Например, если вы назвали класс COrdersкоманд, то будет класс _COrdersAccessorзаписи пользователя. Хотя класс записей пользователя отображается в представлении классов, дважды щелкнув его кнопкой мыши, вы перейдете вместо него в класс команд или таблиц в файле заголовка. В таких случаях вы можете просмотреть фактическое объявление класса записей пользователя только путем просмотра кода, внедренного атрибутами.

При добавлении или переопределении методов в потребителях на основе атрибутов могут возникать определенные сложности. Например, если вы добавите конструктор _COrdersAccessor в объявление COrders , то заметите, что в действительности конструктор добавляется во внедренный класс COrdersAccessor . С помощью такого конструктора можно инициализировать столбцы или параметры, но вы не сможете создать таким образом конструктор копий, поскольку он не может напрямую создать экземпляр объекта COrdersAccessor. Если нужен конструктор (или другой метод) непосредственно в классе COrders, рекомендуется определить новый класс, производный от COrders, и добавить в него необходимые методы.

В следующем примере мастер создает объявление класса COrders, но класс записей пользователя COrdersAccessor не появляется, поскольку его вводят атрибуты.

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

Объявление внедренного класса команд выглядит следующим образом:

class CProducts : public CCommand<CAccessor<_CProductsAccessor>>

Большая часть внедренного кода аналогична версии на основе шаблона. Основные различия — во внедренных методах, которые описаны в разделе Методы, создаваемые мастером потребителя.

Сведения о просмотре внедренного кода см. в разделе Отладка внедренного кода.

См. также

Создание объекта-получателя OLE DB с помощью мастера