TN053. Пользовательские процедуры DFX для классов баз данных DAO
Примечание.
DAO используется с базами данных Access и поддерживается до Office 2013. Версия DAO 3.6 является окончательной и считается устаревшей. Среда и мастеры Visual C++ не поддерживают DAO (хотя классы DAO включены и их можно использовать). Корпорация Майкрософт рекомендует использовать шаблоны OLE DB или ODBC и MFC для новых проектов. Для обслуживания существующих приложений следует использовать только DAO.
В этой технической записке описывается механизм обмена полями записей DAO (DFX). Чтобы понять, что происходит в подпрограммах DFX, DFX_Text
функция будет подробно описана в качестве примера. В качестве дополнительного источника информации для этой технической заметки можно просмотреть код для других отдельных функций DFX. Возможно, вам не потребуется настраиваемая подпрограмма DFX, так как вам может потребоваться настраиваемая подпрограмма RFX (используется с классами базы данных ODBC).
Эта техническая заметка содержит следующее:
Обзор DFX
Примеры использования exchange полей записи DAO и динамической привязки
Обзор DFX
Механизм обмена полями записей DAO (DFX) используется для упрощения процедуры извлечения и обновления данных при использовании CDaoRecordset
класса. Процесс упрощается с помощью элементов CDaoRecordset
данных класса. CDaoRecordset
Исходя из этого, можно добавить элементы данных в производный класс, представляющий каждое поле в таблице или запросе. Этот механизм "статической привязки" прост, но это не может быть метод получения и обновления данных для всех приложений. DFX извлекает каждое ограничивающее поле при каждом изменении текущей записи. Если вы разрабатываете приложение с учетом производительности, которое не требует получения каждого поля при изменении валюты, "динамическая привязка" через CDaoRecordset::GetFieldValue
и CDaoRecordset::SetFieldValue
может быть методом доступа к данным.
Примечание.
DFX и динамическая привязка не являются взаимоисключающими, поэтому можно использовать гибридное использование статической и динамической привязки.
Пример 1. Использование только exchange полей записи DAO
(предполагается, что производный CDaoRecordset
класс CMySet
уже открыт)
// Add a new record to the customers table
myset.AddNew();
myset.m_strCustID = _T("MSFT");
myset.m_strCustName = _T("Microsoft");
myset.Update();
Пример 2. Использование динамической привязки только
(предполагается, что используется CDaoRecordset
класс, rs
и он уже открыт)
// Add a new record to the customers table
COleVariant varFieldValue1 (_T("MSFT"),
VT_BSTRT);
//Note: VT_BSTRT flags string type as ANSI,
instead of UNICODE default
COleVariant varFieldValue2 (_T("Microsoft"),
VT_BSTRT);
rs.AddNew();
rs.SetFieldValue(_T("Customer_ID"),
varFieldValue1);
rs.SetFieldValue(_T("Customer_Name"),
varFieldValue2);
rs.Update();
Пример 3. Использование exchange полей записи DAO и динамической привязки
(предполагается, что просмотр данных сотрудника с CDaoRecordset
производным классом emp
)
// Get the employee's data so that it can be displayed
emp.MoveNext();
// If user wants to see employee's photograph,
// fetch it
COleVariant varPhoto;
if (bSeePicture)
emp.GetFieldValue(_T("photo"),
varPhoto);
// Display the data
PopUpEmployeeData(emp.m_strFirstName,
emp.m_strLastName,
varPhoto);
Принцип работы DFX
Механизм DFX работает аналогично механизму обмена полями записей (RFX), используемому классами ODBC MFC. Принципы DFX и RFX одинаковы, но существуют многочисленные внутренние различия. Дизайн функций DFX был таким, что практически все коды разделяются отдельными подпрограммами DFX. На самом высоком уровне DFX делает лишь несколько вещей.
DFX создает предложение SQL SELECT и предложение SQL PARAMETERS при необходимости.
DFX создает структуру привязки, используемую функцией DAO
GetRows
(подробнее об этом далее).DFX управляет буфером данных, используемым для обнаружения полей грязное (если используется двойное буферизация).
DFX управляет массивами состояний NULL и DIRTY и задает значения при необходимости при обновлении.
В основе механизма DFX лежит CDaoRecordset
функция производного класса DoFieldExchange
. Эта функция отправляет вызовы отдельных функций DFX соответствующего типа операции. Перед вызовом DoFieldExchange
внутренних функций MFC задайте тип операции. В следующем списке показаны различные типы операций и краткое описание.
Операция | Description |
---|---|
AddToParameterList |
Создание предложения PARAMETERS |
AddToSelectList |
Создание предложения SELECT |
BindField |
Настройка структуры привязки |
BindParam |
Задает значения параметров |
Fixup |
Задает состояние NULL |
AllocCache |
Выделяет кэш для грязное проверка |
StoreField |
Сохраняет текущую запись в кэш |
LoadField |
Восстановление кэша в значениях элементов |
FreeCache |
Освобождает кэш |
SetFieldNull |
Задает состояние поля и значение NULL |
MarkForAddNew |
Помечает поля грязное, если не ПСЕВДО NULL |
MarkForEdit |
Помечает поля грязное, если кэш не соответствует |
SetDirtyField |
Задает значения полей, помеченные как грязное |
В следующем разделе все операции подробно описаны.DFX_Text
Наиболее важной функцией для понимания процесса обмена полями записей DAO является то, что она использует GetRows
функцию CDaoRecordset
объекта. Функция DAO GetRows
может работать несколькими способами. Эта техническая заметка будет кратко описыватьGetRows
, как она находится за пределами область этой технической заметки.
DAO GetRows
может работать несколькими способами.
Он может одновременно получать несколько записей и несколько полей данных. Это позволяет ускорить доступ к данным с помощью сложности работы с большой структурой данных и соответствующими смещениями к каждому полю и для каждой записи данных в структуре. MFC не использует этот механизм получения нескольких записей.
Другой способ
GetRows
— разрешить программистам указывать адреса привязки для полученных данных каждого поля для одной записи данных.DAO также будет "обратный вызов" в вызывающий объект для столбцов переменной длины, чтобы разрешить вызывающему объекту выделять память. Эта вторая функция имеет преимущество свести к минимуму количество копий данных, а также разрешить прямое хранение данных в члены класса (
CDaoRecordset
производный класс). Второй механизм — это метод MFC, который используется для привязки к элементам данных в производныхCDaoRecordset
классах.
Что делает пользовательская подпрограмма DFX
Очевидно, что наиболее важная операция, реализованная в любой функции DFX, должна быть способностью настроить необходимые структуры данных для успешного вызова GetRows
. Существует ряд других операций, которые функция DFX также должна поддерживать, но ни один из них не является столь важным или сложным, как правильно подготовиться к вызову GetRows
.
Использование DFX описано в интерактивной документации. По сути, существует два требования. Во-первых, члены должны быть добавлены в производный класс для каждого связанного CDaoRecordset
поля и параметра. После этого CDaoRecordset::DoFieldExchange
следует переопределить. Обратите внимание, что тип данных элемента важен. Он должен соответствовать данным из поля в базе данных или, по крайней мере, быть преобразованным в этот тип. Например, числовое поле в базе данных, например длинное целое число, всегда может быть преобразовано в текст и привязано CString
к члену, но текстовое поле в базе данных может не обязательно быть преобразовано в числовое представление, например длинное целое число и привязанное к длинному целочисленного элемента. DAO и ядро СУБД Microsoft Jet отвечают за преобразование (а не MFC).
Сведения о DFX_Text
Как упоминание ранее, лучший способ объяснить, как работает DFX, заключается в работе с примером. Для этой цели DFX_Text
следует работать довольно хорошо, чтобы обеспечить по крайней мере базовое понимание DFX.
AddToParameterList
Эта операция создает предложение SQL PARAMETERS ("
Parameters <param name>, <param type> ... ;
"), необходимое Jet. Каждый параметр называется и типируется (как указано в вызове RFX). См. функцию функцииCDaoFieldExchange::AppendParamType
, чтобы просмотреть имена отдельных типов. В случаеDFX_Text
типа используется текст.AddToSelectList
Создает предложение SQL SELECT . Это довольно прямо вперед, так как имя столбца, указанное вызовом DFX, просто добавляется ("
SELECT <column name>, ...
").BindField
Наиболее сложные операции. Как упоминание ранее это место, где настраивается структура привязки DAO, используемая
GetRows
. Как видно из кода вDFX_Text
типах информации в структуре, включите используемый тип DAO (DAO_CHAR или DAO_WCHAR в случаеDFX_Text
). Кроме того, используется тип привязки. В предыдущем разделеGetRows
было описано лишь кратко, но было достаточно объяснить, что тип привязки, используемой MFC, всегда является прямой привязкой адресов (DAOBINDING_DIRECT). Кроме того, для привязки столбцов переменной длины (напримерDFX_Text
) используется привязка обратного вызова, чтобы MFC может управлять выделением памяти и указывать адрес правильной длины. Это означает, что MFC всегда может сообщить DAO "где" поместить данные, что позволяет привязать привязку непосредственно к переменным-членам. Остальная часть структуры привязки заполняется такими вещами, как адрес функции обратного вызова выделения памяти и тип привязки столбца (привязка по имени столбца).BindParam
Это простая операция, которая вызывает
SetParamValue
значение параметра, указанное в члене параметра.Fixup
Заполняет состояние NULL для каждого поля.
SetFieldNull
Эта операция помечает только состояние каждого поля как NULL и задает значение переменной-члена для PSEUDO_NULL.
SetDirtyField
Вызовы
SetFieldValue
для каждого поля, помеченного грязное.
Все остальные операции выполняются только с использованием кэша данных. Кэш данных — это дополнительный буфер данных в текущей записи, которая используется для упрощения определенных действий. Например, поля "грязное" можно автоматически обнаружить. Как описано в онлайн-документации, ее можно отключить полностью или на уровне поля. Реализация буфера использует карту. Эта карта используется для сопоставления динамически выделенных копий данных с адресом поля "привязанный" (или CDaoRecordset
производный элемент данных).
AllocCache
Динамически выделяет кэшированное значение поля и добавляет его в карту.
FreeCache
Удаляет кэшированное значение поля и удаляет его из карты.
StoreField
Копирует текущее значение поля в кэш данных.
LoadField
Копирует кэшированное значение в элемент поля.
MarkForAddNew
Проверяет, является ли текущее значение поля не NULL и помечает его грязное при необходимости.
MarkForEdit
Сравнивает текущее значение поля с кэшем данных и помечает грязное при необходимости.
Совет
Моделиируйте пользовательские процедуры DFX в существующих подпрограммах DFX для стандартных типов данных.
См. также
Технические примечания по номеру
Технические примечания по категории