ASP.NET:如何在一个应用程序中支持两种数据库类型?(Access,MS SQL Server 2008 Express)

ASP.NET:如何在一个应用程序中支持两种数据库类型?(Access,MS SQL Server 2008 Express),asp.net,database,ms-access,sql-server-express,dbcommand,Asp.net,Database,Ms Access,Sql Server Express,Dbcommand,我正在开发的ASP.NET web应用程序需要支持两种不同类型的数据库,即Access和MS SQL Server 2008 Express 我已经在web.config中存储了每种数据库类型的连接字符串,还有另一个web.config值指定要使用哪种数据库类型。因此,我可以毫无问题地获得正确的连接字符串 最大的问题是数据库对象。对于我已经实现的Access,我在代码中使用对象OleDbConnection、OleDbCommand和OleDbDataReader来进行数据库调用 对于SQL S

我正在开发的ASP.NET web应用程序需要支持两种不同类型的数据库,即Access和MS SQL Server 2008 Express

我已经在web.config中存储了每种数据库类型的连接字符串,还有另一个web.config值指定要使用哪种数据库类型。因此,我可以毫无问题地获得正确的连接字符串

最大的问题是数据库对象。对于我已经实现的Access,我在代码中使用对象OleDbConnection、OleDbCommand和OleDbDataReader来进行数据库调用

对于SQL Server,我似乎不能使用这些对象,但我需要使用对象SqlConnection、SqlCommand和SqlDataReader来完成基本相同的任务

我希望尽可能多地重用当前代码,而不必为每种数据库类型创建两个单独的块。(我有很多方法将OleDbDataReader作为参数——例如,我不希望每个方法都有两个。)

我注意到连接对象都继承自DbConnection。数据读取器(DbDataReader)和命令(DbCommand)也是如此

是否可以使用我现有的代码进行访问,将所有Ole对象替换为Db对象,然后根据当前数据库类型将这些对象转换为正确的类型

是否有在一个ASP.NET应用程序中支持两种数据库类型的最佳实践


如果有帮助的话,我可以添加一些代码。谢谢。

是的,从framework 2.0中,所有数据读取器都继承自
DbDataReader
类,因此您的方法可以采用
DbDataReader
替代
OleDbDataReader
,并且您可以将这些方法用于任何数据库

但是,这些数据库具有不同的SQL方言,因此您要么只能使用在您使用的所有数据库中工作的特性,要么对某些任务进行单独的查询


差异的一个具体示例是Access使用数据文本,如
\2010-09-24
,而SQL Server使用日期文本,如
'2010-09-24'
。一般来说,与日期有关的大部分内容都不同。

您可能缺少的链接是dbProviderFactorys类的功能。使用此类(以及System.Data.Common中的关联帮助程序),您可以抽象提供程序,并使用对基类的引用(例如DbConnection和DbCommand)来完成这项工作。看起来是这样的:

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...
}
获取提供程序名称有点困难,但应该是与DbProviderFactorys.GetFactoryClasses()返回的名称之一匹配的不变类名。或者,您可以简单地对它们进行硬编码。它们变化不大,但它是嵌入在代码中的神奇字符串,最终可能会导致问题


可以通过factory.CreateCommandBuilder访问其他功能,这些功能可以帮助您了解提供者处理参数等方面的差异。

感谢您提供的日期提示。另一个SQL方言的差异是强制转换:在Access中,要将“10”强制转换为整数,我使用CInt('10'),但在SQL Server中,我使用强制转换('10'作为Int)这是有效的。我将所有期望OleDbDataReader对象的方法改为期望DbDataReader对象。在创建读取器的方法中,我根据给定的数据库类型返回OleDbDataReader对象或SqlDataReader对象。