TN054 : Appeler DAO directement lorsque vous utilisez les classes DAO MFC
[!REMARQUE]
Dans Visual C++ .NET, les Assistants et l'environnement Visual C++ ne prennent plus en charge DAO (même si les classes DAO sont incluses et que vous pouvez toujours les utiliser).Microsoft recommande que vous utilisez Modèles OLE DB ou ODBC et MFC pour les nouveaux projets.Vous ne devez utiliser DAO que dans les applications existantes.
L'utilisation des classes de bases de données DAO MFC, il peut y avoir des situations où il est nécessaire d'utiliser DAO directement.En général, ce n'est pas le cas, mais MFC fournissait des mécanismes d'assistance pour simplifier effectuer des appels directs DAO simples en combinant l'utilisation des classes MFC avec des appels directs DAO.Effectuer des appels directs DAO aux méthodes de l'objet DAO par MFC managé doit exiger que quelques lignes de code.Si vous devez créer et utiliser les objets DAO qui ne sont pas gérés par les MFC, vous devez effectuer un peu plus de travail en appelant en fait Version finale sur l'objet.Cette note technique explique quand vous pouvez appeler DAO directement, ce que les programmes d'assistance MFC peuvent faire pour vous aider, et comment utiliser les interfaces DAO OLE.Enfin, cette remarque fournit des fonctions d'exemple montrant comment appeler DAO directement pour les fonctionnalités de sécurité DAO.
Lorsque effectuer des appels directs DAO
Les cas les plus courantes pour effectuer des appels directs DAO se produisent lorsque les collections doivent être actualisées ou lorsque vous implémentez des fonctionnalités non encapsulées par MFC.La fonctionnalité la plus significative non exposée par MFC est sécurité.Si vous souhaitez implémenter des fonctionnalités de sécurité, vous devrez utiliser les objets d'utilisateurs et de groupes DAO directement.Outre la sécurité, il existe quelques autres fonctionnalités de DAO non prises en charge par les MFC.Celles-ci incluent le clonage de recordset et des fonctionnalités de réplication de base de données ainsi que des ajouts tardive à DAO.
Une vue d'ensemble de DAO et de l'implémentation MFC
L'encapsulation de DAO MFC simplifie l'aide de DAO en gérant de nombreux détails vous n'avez pas à vous préoccuper des petites actions.Cela inclut l'initialisation OLE, la création et la gestion des objets DAO (notamment les objets de collection), de la vérification des erreurs, et de fournir une interface fortement typée et plus simple (aucun variant ou arguments d' BSTR ).Vous pouvez effectuer des appels directs DAO et encore tirer parti de ces fonctionnalités.Tout votre code doit faire consiste à appeler Version finale pour tous les objets créés par les appels directs DAO et de ne pas modifier les pointeurs d'interface l'un des que MFC peut compter sur en interne.Par exemple, ne modifiez pas le membre de m_pDAORecordset d'un objet ouvert d' CDaoRecordset à moins que vous compreniez les ramifications internes.Vous pouvez, toutefois, utiliser l'interface de m_pDAORecordset pour appeler DAO directement pour obtenir la collection de champs.Dans ce cas le membre de m_pDAORecordset ne sera pas modifié.Vous devez simplement appeler Version finale sur l'objet collection de champs lorsque vous avez terminé avec l'objet.
Description des programmes d'assistance pour simplifier les appels de DAO
Les programmes d'assistance fournis pour faire appeler DAO plus facile sont les mêmes programmes d'assistance qui sont utilisés en interne dans les classes de base de données DAO MFC.Ces programmes d'assistance sont utilisés pour vérifier les codes de retour en appelant direct de DAO, en enregistrant sortie de débogage, la vérification des erreurs prévues, et levant des exceptions appropriées si nécessaire.Il existe deux fonctions d'assistance sous-jacentes et quatre macros qui sont mappées à un de ces deux programmes d'assistance.La meilleure explication consisterait à lire uniquement le code.Voir DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM, et le DAO_TRACE dans AFXDAO.H pour afficher les macros et, consultez AfxDaoCheck et l' AfxDaoTrace dans DAOCORE.CPP.
À l'aide de les interfaces DAO OLE
Les interfaces OLE pour chaque objet dans la hiérarchie d'objet DAO sont définies dans le fichier d'en-tête DBDAOINT.H, qui se trouve dans le dossier \Program Files\Microsoft Visual Studio .NET 2003\VC7\Include.Ces interfaces fournissent des méthodes qui vous permettent de manipuler la hiérarchie complète de DAO.
Pour la plupart des méthodes des interfaces DAO, vous devez manipuler un objet d' BSTR (chaîne longueur- préfixée utilisée dans OLE automation).L'objet d' BSTR généralement est encapsulé dans le type de données de variant .La classe MFC COleVariant lui-même hérite du type de données de variant .Selon que vous générez votre projet pour ANSI ou Unicode, les interfaces DAO retournera ANSI ou Unicode BSTRS.Deux macros, V_BSTR et V_BSTRT, sont utiles pour vérifier que l'interface DAO obtient BSTR du type attendu.
V_BSTR récupérera le membre de bstrVal d' COleVariant.Cette macro est généralement utilisée lorsque vous devez passer le contenu d' COleVariant à une méthode d'interface DAO.Le fragment de code suivant montre les déclarations et l'utilisation réelle pour deux méthodes d'interface DAO DAOUser qui tirent parti de la 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 ) ));
Notez que l'argument d' VT_BSTRT spécifié dans le constructeur d' COleVariant ci-dessus garantit qu'il y aura ANSI BSTR dans COleVariant si vous générez une version ANSI de votre application et un Unicode BSTR de version Unicode de votre application.C'est ce que DAO compte.
L'autre macro, V_BSTRT, récupérera ANSI ou le membre Unicode bstrVal d' COleVariant selon le type de build (ANSI ou Unicode).Le code suivant montre comment récupérer la valeur d' BSTR d' COleVariant dans CString:
COleVariant varName( _T( "MyName" ), VT_BSTRT );
CString str = V_BSTRT( &varName );
Le de V_BSTRT, ainsi que d'autres techniques d'ouvrir d'autres types qui sont stockés dans COleVariant, est illustrée dans l'exemple de DAOVIEW.Spécifiquement, cette interprétation est exécutée dans la méthode de CCrack::strVARIANT .Cette méthode, dans la mesure du possible, traduit la valeur d' COleVariant en instance d' CString.
Exemple simple d'un appel direct à DAO
Les situations peuvent survenir lorsqu'il est nécessaire d'actualiser des objets de collection sous-jacents DAO.Normalement, cela ne doit pas être nécessaire, mais il s'agit d'une procédure simple si nécessaire.Un exemple de lorsqu'une collection peut être actualisée est en travaillant dans un environnement multi-utilisateur avec plusieurs utilisateurs créant de nouveaux tabledefs.Dans ce cas votre collection de tabledefs peut devenir périmée.Pour actualiser la collection, vous devez simplement appeler la méthode de Actualiser d'objet collection particulier et vérifier les erreurs :
DAO_CHECK( pMyDaoDatabase->
m_pDAOTableDefs->Refresh( ) );
Notez qu'en cours toutes les interfaces de l'objet collection de DAO sont les détails d'implémentation non documentés des classes de bases de données DAO MFC.
À l'aide de DAO directement pour les fonctionnalités de sécurité DAO
Les classes de bases de données DAO MFC n'encapsulent pas les fonctionnalités de sécurité DAO.Vous devez appeler les méthodes d'interfaces DAO pour utiliser certaines fonctionnalités de sécurité DAO.La fonction suivante définit la base de données système puis modifie le mot de passe d'un utilisateur.Appel de cette fonction trois autres fonctions, qui sont définies par la suite.
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 );
.
.
.
}
Les quatre exemples suivants montrent comment :
Définissez les bases de données DAO de système (fichier de .MDW).
Définissez l'utilisateur et le mot de passe par défaut.
Modifiez le mot de passe d'un utilisateur.
Modifiez le mot de passe d'un fichier de .MDB.
Définition de la base de données système
Vous trouverez ci-dessous une fonction d'exemple pour définir la base de données système qui sera utilisée par une application.Cette fonction doit être appelée avant que tous les autres appels DAO soient effectuées.
// 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 ) );
}
Définition de l'utilisateur et du mot de passe par défaut
Pour définir l'utilisateur et le mot de passe par défaut d'une base de données système, utilisez la fonction suivante :
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 ) );
}
Modifier le mot de passe d'un utilisateur
Pour modifier le mot de passe d'un utilisateur, utilisez la fonction suivante :
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( );
}
Modifier le mot de passe d'un fichier de .MDB
Pour modifier le mot de passe d'un fichier de .MDB, utilisez la fonction suivante :
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();
}