2010-09-23 14 views
3

L'application Web ASP.NET que je développe doit prendre en charge deux types de bases de données différents, à savoir Access et MS SQL Server 2008 Express.ASP.NET: Comment prendre en charge deux types de base de données dans une application? (Accès, MS SQL Server 2008 Express)

J'ai déjà des chaînes de connexion pour chaque type de base de données stockées dans web.config, et j'ai une autre valeur web.config qui spécifie laquelle utiliser. Donc, je peux obtenir la bonne chaîne de connexion sans problème.

Le gros problème vient des objets de base de données. Pour Access, que j'ai déjà implémenté, j'utilise les objets OleDbConnection, OleDbCommand et OleDbDataReader dans le code pour faire les appels de base de données.

Il semble que pour SQL Server, je ne peux pas utiliser ces objets, mais plutôt que j'utiliserais les objets SqlConnection, SqlCommand et SqlDataReader pour faire essentiellement les mêmes choses.

Je souhaite réutiliser autant de mon code actuel que possible et ne pas avoir à créer deux blocs distincts pour chaque type de base de données. (J'ai beaucoup de méthodes qui prennent un OleDbDataReader comme paramètre - je ne veux pas avoir à faire 2 de chacune de ces méthodes, par exemple.)

J'ai remarqué que les objets de connexion héritent tous les deux de DbConnection. Et la même chose est vraie pour les lecteurs de données (DbDataReader) et les commandes (DbCommand).

Serait-il possible de prendre mon code existant pour Access, de remplacer tous les objets Ole par les objets Db, puis de lancer ces objets comme le type approprié en fonction du type de base de données en cours?

Existe-t-il des meilleures pratiques pour prendre en charge deux types de base de données dans une application ASP.NET?

Je peux ajouter une partie de mon code si cela peut aider. Merci.

Répondre

0

Oui, du framework 2.0 tous les lecteurs de données héritent de la classe DbDataReader, afin que vos méthodes pourraient prendre un DbDataReader isntead d'un OleDbDataReader, et vous pouvez utiliser les méthodes avec une base de données. Cependant, les bases de données ont différents dialectes de SQL, vous devez donc rester sur un chemin étroit de fonctionnalités qui fonctionnent dans toutes les bases de données que vous utilisez, ou avoir des requêtes distinctes pour certaines tâches.

Un exemple spécifique de différences est qu'Access utilise des littéraux de données tels que #2010-09-24# tandis que SQL Server utilise des littéraux de date comme '2010-09-24'. Généralement, la plupart des dates sont différentes.

+0

Merci pour le pourboire sur les dates. – Jeremy

+0

Une autre différence de dialecte SQL est la coulée: Dans Access, pour lancer '10' comme Integer, j'utilise CInt ('10 ') Mais dans SQL Server, j'utilise Cast ('10' AS Int) – Jeremy

+0

Cela fonctionne. J'ai changé toutes les méthodes qui s'attendaient à ce qu'un objet OleDbDataReader attende un objet DbDataReader à la place. Dans la méthode qui crée le lecteur, je renvoie un objet OleDbDataReader ou un objet SqlDataReader, selon le type de base de données donné. – Jeremy

0

Le lien qui vous manque probablement est la fonctionnalité de la classe DbProviderFactories. En utilisant cette classe (et les assistants associés également dans System.Data.Common), vous pouvez extraire le fournisseur et utiliser des références aux classes de base (telles que DbConnection et DbCommand) pour effectuer le travail. Il avait l'air quelque chose comme ceci:

private void DoSomething(string provider, string connectionString, string something) 
{  
    DbProviderFactory factory = DbProviderFactories.GetFactory(provider); 
    DbConnection connection = factory.CreateConnection(); 
    connection.ConnectionString = connectionString; 
    DbCommand command = connection.CreateCommand(); 
    command.CommandText = something; 
    DbDataReader reader = command.ExecuteReader(); 
    //etc... 
} 

Le nom du fournisseur est un peu difficile à acquérir, mais devrait être le nom de la classe invariant qui correspond à un de ceux retournés par DbProviderFactories.GetFactoryClasses(). Ou, vous pouvez simplement les coder en dur. Ils ne changent pas beaucoup, mais est une chaîne magique intégrée dans votre code et peut causer des problèmes finalement.

Des fonctions supplémentaires peuvent être accédées par factory.CreateCommandBuilder qui peut vous aider à traverser les différences dans la façon dont les fournisseurs gèrent des choses comme les paramètres et autres.