Классы, создаваемые мастером объекта-получателя
Обновлен: Ноябрь 2007
При создании объекта-получателя с помощью мастера объекта-получателя ATL OLE DB можно использовать шаблоны OLE DB или атрибуты OLE DB. В обоих классах мастер создает класс команд и класс записей пользователя. В классе команд содержится код, открывающий источник данных, и набор строк, указанный в мастере. В классе записей пользователя содержится сопоставление столбцов для выбранной таблицы базы данных. Однако создаваемый код в каждом случае будет отличаться.
При выборе шаблонного потребителя мастер создает класс команд и класс записей пользователя. Имя класса команд будет соответствовать введенному в поле "Класс" в мастере (например, CProducts), а имя класса записей пользователя — имени формы "ClassNameAccessor" (например, CProductsAccessor). Оба класса находятся в файле заголовка объекта-получателя.
При выборе объекта-получателя с атрибутом имя класса записей пользователя будет соответствовать имени формы "_ClassNameAccessor" и будет введено. Это означает, что в текстовом редакторе можно будет просматривать только класс команд, а класс записей пользователя — только как введенный код. Дополнительные сведения о просмотре введенного кода см. в разделе Отладка введенного кода.
В следующем примере используется класс команд, созданный в таблице "Продукты" базы данных "Борей". В примере демонстрируется код потребителя, созданный мастером, для класса команд и класса записей пользователя.
Шаблонные классы записей пользователя
Если объект-получатель 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 выбрать Change, Insert или Delete, будут задаваться соответствующие свойства (свойство 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> >
Введенный код почти полностью идентичен шаблонной версии. Основные различия — во введенных методах, которые описаны в разделе Методы, создаваемые мастером объекта-получателя.
Дополнительные сведения о просмотре введенного кода см. в разделе Отладка введенного кода.