TN054: Chamar o DAO diretamente ao usar Classes MFC DAO
Observação |
---|
Até a data do Visual C++ .NET, o ambiente e assistentes Visual C++ não suportam DAO (embora as classes de DAO são incluídas e você ainda pode usar o).Microsoft recomendável que você use Modelos do OLE DB OLE DB ou ODBC e MFC para novos projetos.Você deve usar DAO em manter aplicativos existentes. |
Ao usar as classes de banco de dados MFC DAO, pode haver situações onde é necessário usar diretamente DAO.Geralmente, isso não será os casos, mas o MFC forneceu alguns mecanismos auxiliar para facilitar fazer chamadas diretas de DAO simples quando combinar o uso MFC classe com chamadas diretas de DAO.Fazer chamadas diretas de DAO métodos de um objeto MFC- gerenciado de DAO deve solicitar apenas algumas linhas de código.Se você precisa criar e usar objetos de DAO que não são gerenciados pelo MFC, você precisará tornar um pouco mais trabalho realmente chamando Release no objeto.Essa técnica nota explica quando você desejar chamar diretamente DAO, o que os auxiliares MFC podem fazer para ajudá-lo, e como usar o OLE DAO interfaces.Finalmente, essa observação fornece algumas funções de exemplo que mostram como chamar DAO diretamente para recursos de segurança de DAO.
Quando fazer chamadas diretas de DAO
As situações a mais comum para fazer chamadas diretas de DAO ocorrem quando as coleções precisam ser atualizados ou quando você estiver implementando recursos não envolvidos pelo MFC.O recurso mais significativo não expostas pelo MFC é segurança.Se você deseja implementar recursos de segurança, você precisará usar os usuários de DAO e o grupo objetos diretamente.Além de segurança, há alguns outros recursos de DAO não suportados pelo MFC.Esses incluem recursos de replicação de animação e do banco de dados do recordset bem como algumas adições atrasadas a DAO.
Uma breve visão geral da implementação de DAO e de MFC
O envoltório MFC de DAO facilita usando DAO manipular muitos dos detalhes para que você não tem que se preocupar sobre as coisas pequenas.Isso inclui a inicialização do OLE, a criação e o gerenciamento de objetos de DAO (especialmente os objetos de coleção), a verificação de erros, e fornecendo uma interface fortemente tipada, mais simples (nenhum VARIANT ou argumentos de BSTR ).Você pode fazer chamadas diretas de DAO e ainda aproveitar esses recursos.Tudo o que o código deve fazer é chamar Release para todos os objetos criados por chamadas diretas de DAO e não modificar alguns dos ponteiros de interface que o MFC pode confiar sobre internamente.Por exemplo, não modifique o membro de m_pDAORecordset de um objeto de abertura de CDaoRecordset a menos que você saiba todas as ramificação internas.Você pode, no entanto, usar a interface de m_pDAORecordset para chamar diretamente DAO para obter a coleção de campos.O membro de m_pDAORecordset não será alterado nesse caso.Você simplesmente precisa chamar Versão no objeto de coleção fields quando você terminar com o objeto.
Descrição de auxiliares para fazer chamadas de DAO
Os auxiliares fornecidos para fazer chamar DAO mais fácil são os mesmos auxiliares que são usados internamente nas classes de banco de dados MFC DAO.Esses auxiliares são usados para verificar os códigos de retorno para fazer uma chamada direto de DAO, ao registrar saída de depuração, verifique para ver se há erros esperados, e para lançar exceções apropriadas se necessário.Há duas funções subjacentes auxiliar e quatro macros que mapeiam a um desses dois auxiliares.A melhor explicação seria simplesmente lê o código.Consulte DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM, e DAO_TRACE em AFXDAO.H para ver as macros, consulte e AfxDaoCheck e AfxDaoTrace em DAOCORE.CPP.
Usando as interfaces do OLE DAO
As interfaces VELHOS para cada objeto na hierarquia de objetos de DAO são definidas no arquivo de cabeçalho DBDAOINT.H, que está localizado no \ program files \ Microsoft Visual Studio .NET 2003 \ \ VC7 inclui o diretório.Essas classes fornecem métodos que permitem que você manipule a hierarquia de DAO inteira.
Para muitos dos métodos em interfaces de DAO, você precisará manipular um objeto de BSTR (uma cadeia de caracteres comprimento- prefixo usada na automação OLE.)O objeto de BSTR é encapsulado normalmente no tipo de dados VARIANT .A classe COleVariant próprio MFC herda do tipo de dados VARIANT .Dependendo se você compila seu projeto para ANSI, Unicode ou interfaces de DAO irão ANSI ou Unicode BSTRS.Dois macros, V_BSTR e V_BSTRT, são úteis para garantir que a interface de DAO obtém BSTR do tipo esperado.
V_BSTR extrairá o membro de bstrVal de COleVariant.Este macro é normalmente usado quando você precisar passar o conteúdo de COleVariant para um método de uma interface de DAO.O fragmento de código a seguir mostra as declarações e o uso real para dois métodos de interface de DAO DAOUser que aproveitam de macro de V_BSTR :
COleVariant varOldName;
COleVariant varNewName( _T("NewUser"), VT_BSTRT );
// Code to assign pUser to a valid value omitted
DAOUser *pUser = NULL;
// These method declarations were taken from DBDAOINT.H
// STDMETHOD(get_Name) (THIS_ BSTR FAR* pbstr) PURE;
// STDMETHOD(put_Name) (THIS_ BSTR bstr) PURE;
DAO_CHECK( pUser->get_Name( &V_BSTR ( &varOldName ) ));
DAO_CHECK( pUser->put_Name( V_BSTR ( &varNewName ) ));
Observe que o argumento de VT_BSTRT especificado no construtor de COleVariant anterior garante que haja ANSI BSTR em COleVariant se você criar uma versão ANSI do seu aplicativo e um BSTR Unicode para uma versão Unicode do seu aplicativo.Este é o que DAO espera.
O outro macros, V_BSTRT, extrairá ANSI ou membro Unicode bstrVal de COleVariant dependendo do tipo de compilação (ANSI ou Unicode).O código a seguir demonstra como extrair o valor de BSTR de COleVariant em CString:
COleVariant varName( _T( "MyName" ), VT_BSTRT );
CString str = V_BSTRT( &varName );
A macro de V_BSTRT , juntamente com outras técnicas abrir outros tipos que são armazenados em COleVariant, é demonstrado no exemplo de DAOVIEW.Especificamente, essa conversão é executada no método de CCrack::strVARIANT .Esse método, sempre que possível, converte o valor de COleVariant em uma instância de CString.
Um exemplo simples de chamada direto a DAO
As situações podem ocorrer quando for necessário atualizar os objetos de coleção subjacente de DAO.Normalmente, isso não deve ser necessário, mas é um procedimento simples se necessário.Um exemplo de quando uma coleção pode precisar ser atualizado é para operar em um ambiente multiusuário com vários usuários que criam novos tabledefs.Nesse caso sua coleção de tabledefs pode se tornar velha.Para atualizar a coleção, você simplesmente precisa chamar o método de Atualizar do objeto específico de uma coleção e de verificando erros:
DAO_CHECK( pMyDaoDatabase->
m_pDAOTableDefs->Refresh( ) );
Observe que atualmente todas as interfaces de objeto de coleção de DAO são detalhes de implementação indocumentados as classes de banco de dados MFC DAO.
Usando DAO diretamente para recursos de segurança de DAO
As classes de banco de dados MFC DAO não envolvem recursos de segurança de DAO.Você deve chamar métodos de interfaces de DAO para usar recursos de segurança de qualquer DAO.A função a seguir define o banco de dados do sistema e altera a senha do usuário.Este chamadas de função três outras funções, que são definidas posteriormente.
void ChangeUserPassword( )
{
// Specify path to the Microsoft Access
// system database
CString strSystemDB =
_T( "c:\\Program Files\\MSOffice\\access\\System.mdw" );
// Set system database before MFC initilizes DAO
// NOTE: An MFC module uses only one instance
// of a DAO database engine object. If you have
// called a DAO object in your application prior
// to calling the function below, you must call
// AfxDaoTerm to destroy the existing database
// engine object. Otherwise, the database engine
// object already in use will be reused, and setting
// a system datbase will have no effect.
//
// If you have used a DAO object prior to calling
// this function it is important that DAO be
// terminated with AfxDaoTerm since an MFC
// module only gets one copy of the database engine
// and that engine will be reused if it hasn't been
// terminated. In other words, if you do not call
// AfxDaoTerm and there is currently a database
// initialized, setting the system database will
// have no affect.
SetSystemDB( strSystemDB );
// User name and password manually added
// by using Microsoft Access
CString strUserName = _T( "NewUser" );
CString strOldPassword = _T( "Password" );
CString strNewPassword = _T( "NewPassword" );
// Set default user so that MFC will be able
// to log in by default using the user name and
// password from the system database
SetDefaultUser( strUserName, strOldPassword );
// Change the password. You should be able to
// call this function from anywhere in your
// MFC application
ChangePassword( strUserName, strOldPassword,
strNewPassword );
.
.
.
}
Os quatro exemplos a seguir demonstram como:
Defina o banco de dados do sistema DAO (arquivo de .MDW).
Defina o usuário e a senha padrão.
Alterar a senha de um usuário.
Alterar a senha de um arquivo de .MDB.
Definindo o banco de dados do sistema
A seguir está uma função de exemplo para definir o banco de dados do sistema que será usado por um aplicativo.Essa função deve ser chamado antes que quaisquer outros chamadas de DAO são feitos.
// Set the system database that the
// DAO database engine will use
void SetSystemDB( CString & strSystemMDB )
{
COleVariant varSystemDB( strSystemMDB, VT_BSTRT );
// Initialize DAO for MFC
AfxDaoInit( );
DAODBEngine* pDBEngine = AfxDaoGetEngine( );
ASSERT( pDBEngine != NULL );
// Call put_SystemDB method to set the
// system database for DAO engine
DAO_CHECK( pDBEngine->put_SystemDB( varSystemDB.bstrVal ) );
}
Definindo o usuário e a senha padrão
Para definir o usuário e a senha padrão para um banco de dados do sistema, use a função a seguir:
void SetDefaultUser(CString & strUserName, CString & strPassword)
{
COleVariant varUserName( strUserName, VT_BSTRT );
COleVariant varPassword( strPassword, VT_BSTRT );
DAODBEngine* pDBEngine = AfxDaoGetEngine( );
ASSERT( pDBEngine != NULL );
// Set default user:
DAO_CHECK( pDBEngine->put_DefaultUser( varUserName.bstrVal ) );
// Set default password:
DAO_CHECK( pDBEngine->put_DefaultPassword( varPassword.bstrVal ) );
}
Alterando a senha do usuário
Para alterar uma senha de usuário, use a função a seguir:
void ChangePassword( CString &strUserName,
CString &strOldPassword,
CString &strNewPassword )
{
// Create (open) a workspace
CDaoWorkspace wsp;
CString strWspName = _T( "Temp Workspace" );
wsp.Create( strWspName, strUserName,
strOldPassword );
wsp.Append( );
// Determine how many objects there are
// in the Users collection
short nUserCount;
short nCurrentUser;
DAOUser *pUser = NULL;
DAOUsers *pUsers = NULL;
// Side-effect is implicit OLE AddRef( )
// on DAOUser object:
DAO_CHECK( wsp.m_pDAOWorkspace->get_Users( &pUsers ) );
// Side-effect is implicit OLE AddRef( )
// on DAOUsers object
DAO_CHECK( pUsers->get_Count( &nUserCount ) );
// Traverse through the list of users
// and change password for the userid
// used to create/open the workspace
for( nCurrentUser = 0; nCurrentUser < nUserCount;
nCurrentUser++ )
{
COleVariant varIndex( nCurrentUser, VT_I2 );
COleVariant varName;
// Retrieve information for user nCurrentUser
DAO_CHECK( pUsers->get_Item( varIndex, &pUser ) );
// Retrieve name for user nCurrentUser
DAO_CHECK( pUser->get_Name( &V_BSTR( &varName ) ) );
CString strTemp = V_BSTRT( &varName );
// If there is a match, change the password
if( strTemp == strUserName )
{
COleVariant varOldPwd( strOldPassword,
VT_BSTRT );
COleVariant varNewPwd( strNewPassword,
VT_BSTRT );
DAO_CHECK( pUser->NewPassword( V_BSTR( &varOldPwd ),
V_BSTR( &varNewPwd ) ) );
TRACE( "\t Password is changed\n" );
}
}
// Clean up: decrement the usage count
// on the OLE objects
pUser->Release( );
pUsers->Release( );
wsp.Close( );
}
Alterando a senha de um Arquivo .MDB
Para alterar a senha de um arquivo de .MDB, use a função a seguir:
void SetDBPassword( LPCTSTR pDB, LPCTSTR pszOldPassword, LPCTSTR pszNewPassword )
{
CDaoDatabase db;
CString strConnect( _T( ";pwd=" ) );
// the database must be opened as exclusive
// to set a password
db.Open( pDB, TRUE, FALSE,
strConnect + pszOldPassword );
COleVariant NewPassword( pszNewPassword, VT_BSTRT ),
OldPassword( pszOldPassword, VT_BSTRT );
DAO_CHECK( db.m_pDAODatabase->NewPassword( V_BSTR( &OldPassword ),
V_BSTR( &NewPassword ) ) );
db.Close();
}