在不实际编码两个 DAL 的情况下实现这种 DB 不可知论的好方法是什么?我听说数据访问应用程序块适用于此。
8 回答
您还可以查看各种 ORM 库,例如 NHibernate。当您针对多个数据库时,最好寻找一种可以从配置文件或代码创建数据库的工具。这将防止您必须在 MySQL 和 MSSql 中创建相同的数据库。
一种选择是使用 System.Data 命名空间中的 IDbConnection、IDbCommand 等类进行编码,而不是使用 System.Data.SqlClient 中的 SQL Server 特定类(SqlConnection、SqlCommand)或相应的 MySQL 特定类。您仍然需要为您正在使用的特定数据库创建连接类的实例,但从那里您可以使用通用接口。
http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/1175d7ea-f5b4-442f-9155-08bf8b2ba06c/和http://www.15seconds.com/issue/040127.htm有一些示例代码。
使用 MySQL 的 ADODB 抽象库。本机 MySQL 库调用非常丑陋和原始,因此无论如何您都可能需要更高级别的东西。
好吧,正如其他人指出的那样,尝试将自己从所涉及的实际类中抽象出来。正如 AHd54 指出的那样,这可能涉及使用接口,或者类似的东西。
但这只会让你成功一半。
您需要执行的 SQL 也会有所不同,如下所示:
- 参数名称语法
- 位置参数与命名参数
- 函数名称
- 一些语法差异,比如如何指定只给我前 N 行
如果您需要涵盖所有这些内容,并且不能或不会使用 ORM(尽管它们很少让您 100% 到达那里),那么一种方法是创建您自己的类,这些类不仅抽象出所涉及的实际类,但也会进行某种类型的 SQL 重写来处理代码差异。
我已经走上了重写的道路,因此,如果您需要对此的指示,请在此答案中添加评论并提出问题,我将相应地更新答案。
ORM 框架将帮助您实现与 RDBMS 无关的基础架构,但如果您使用 UDF 和存储过程,您仍然必须保留单独的 DAL。因此,您可能不会使用触发器、T-SQL、更新视图和 CLR 托管的 C# 代码。您只需映射实体和对象。
ADO.NET 在大多数项目中都能做得很好。如果您需要在 MSSQL 或 MySQL 之间切换,您可以像这样轻松实现与提供者无关的访问:
private static DbProviderFactory _provider = DbProviderFactories.GetFactory(WebConfigurationManager.ConnectionStrings["database"].ProviderName);
private static string _connectionString = WebConfigurationManager.ConnectionStrings["database"].ConnectionString;
public static DbParameter CreateParameter(string name, object value)
{
DbParameter parameter = _provider.CreateParameter();
parameter.ParameterName = name;
parameter.Value = value;
return parameter;
}
public static DataTable SelectAsTable(string query, DbParameter[] parameters)
{
using (DbConnection connection = _provider.CreateConnection())
{
connection.ConnectionString = _connectionString;
using (DbDataAdapter adapter = _provider.CreateDataAdapter())
{
adapter.SelectCommand = connection.CreateCommand();
adapter.SelectCommand.Parameters.AddRange(parameters);
adapter.SelectCommand.CommandText = query;
DataTable table = new DataTable();
adapter.Fill(table);
connection.Close();
return table;
}
}
}
最好的方法是使用 O/RM 工具(实际上通常是任何数据库访问层)。我更喜欢 ActiveRecord,它是 nHibernate 的包装器......
这是一些使用 AR 的示例源代码;Stacked 中运算符对象的代码
.net Provider 模型是专门为解决这个问题而设计的。通过提供一个“提供程序”类来处理您的所有数据库交互并从精心设计的基类继承,您可以以最小的努力换出后端提供程序(用于 sql、mySql (blech)、xml 或其他)。
此外,根据我的经验,ORM 生成的代码无法与有能力的开发人员编写的代码竞争,并且通常会产生更多由它解决的维护问题。ORM 是另一个抽象层,它会导致更慢、更占用资源的代码,这些代码只对那些不熟悉 SQL 的来龙去脉的人来说是必需的。