Шаг 10 - Понимание RFX

RFX - Record Field Exchange. Это механизм обмена данными между классом потомком от CRecordset и самой базой данных. Работа этого механизма по смыслу аналогична работе DDX. Данный механизм применяет ClassWizard при автоматическом создании класса CRecordset.

Для работы с RFX нам необходимо создать сына от класса CRecordset на основе известной структуры базы данных. Я создал в файле ACCESS новую таблицу TABLE3 с одним текстовых полем, и поместил туда две записи. Итак нам известна структура - одна текстовая колонка (не являющаяся ключевым полем). Эта текстовая колонка.

class MyCrec:public CRecordset
{
public:
	MyCrec( CDatabase* pDatabase = NULL);
	virtual void DoFieldExchange(CFieldExchange* pFX);
	CString m_Fam;
};

Как видите ничего необычного нет. Простое наследование, перегрузка конструктора, обьявление функции DoFieldExchange для организации механизма обмена и переменной типа CString для соответствия формату поля колонки из таблицы базы данных. Я не сделал эту переменную private, но Вы можете это делать спокойно.

Реализация конструктора. Просто и ясно :-).

MyCrec::MyCrec( CDatabase* pDatabase)
	:CRecordset(pDatabase)
{
}

Функция обмена:

void MyCrec::DoFieldExchange(CFieldExchange* pFX)
{
	pFX->SetFieldType(CFieldExchange::outputColumn);
	RFX_Text(pFX,_T("Famili"),m_Fam);
}

В простом приближении правило простое. Перед функциями обмена надо вызвать SetFieldType.

Опять сильно упрошено. Эта функция позволяет Вам произвести обмен между переменной типа CString и текущей строкой в конкретной колонке базы данных. У меня колонка называется Famili. Обратите внимание на то, что строка помещена в конструкцию _T(...), это сделано для гарантии создания объекта типа CString. А вот ниже полное описание этой функции.

void RFX_Text( CFieldExchange* pFX, const char* szName,
	CString& value, int nMaxLength = 255, int nColumnType = SQL_VARCHAR,
	short nScale = 0 );

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

void CDatebaseDlg::OnOpen() 
{ 
	MyCrec cr(NULL);
	try
	{
		cr.m_nFields=1;
		cr.Open(CRecordset::dynaset, "SELECT *  FROM TABLE3"); 
		if(cr.CanAppend()) 
		{
			cr.AddNew();
		}
		cr.m_Fam="Kaev";
		cr.Update();
		cr.Close(); 
	}
	catch(CDBException cdb)
	{
		AfxMessageBox(cdb.m_strStateNativeOrigin);
	}
}

Итак, объявляем объект от нашего класса. Устанавливаем количество колонок в m_nFields. Открываем набор записей, как динамический (т.е. в который можно вносить измения) - dynaset. CanAppend проверяет возможность добавления записей. Запись добавляется пустая. Вводим в переменную содержание и заносим данные непосредственно в базу данных Update.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 22.10.99