我正在设计一个将由数百个客户端调用的 WCF 服务,我对数据库查询运行的类的最佳体系结构有疑问。今天我只访问 SQL Server,所以我有一个内部调用的静态类,它完成创建连接和数据读取器的所有脏活。下面是一个简单的例子:
namespace DBHelper.Utility
{
public static class SqlDBManager
{
public static void RunSql(String pSql, DBParamsHelper pDBParams, String pConnStringConfigName)
{
String sConnectionString = GetConnectionStringFromConfig(pConnStringConfigName);
SqlConnection oConn = new SqlConnectionsConnectionString
oConn.Open();
try
{
SqlCommand oCommand = new SqlCommand(pSql, oConn);
oCommand.CommandTimeout = 0;
if (pDBManagerParams != null)
{
foreach (SqlParameter sqlParam in pDBManagerParams)
{
oCommand.Parameters.Add(sqlParam);
}
}
oCommand.ExecuteNonQuery();
}
finally
{
oConn.Close();
}
}
}
}
现在,我需要添加对运行 Sql Server 和 Oracle 的支持。我最初的想法是声明一个接口(interface),让我现有的 SqlDBManager
实现它,然后开发一个实现相同接口(interface)的 OracleDBManager
。问题是我的类是静态的,静态类不能实现接口(interface)。我希望我的助手类保持静态,因为它更实用,而且我不必在每次需要运行查询时都创建一个新对象。我也想过使用类继承,但是我不能有statis虚方法,所以用处不大。我考虑了一些单例实现,这样我就不必创建类,但是我会在多线程访问上遇到麻烦。
最好的设计模式是什么,这样我就可以在多线程场景中获得出色的性能(非常重要),无需为提高工作效率而进行过多的工作编码(不必创建很多类),并且为 都有一个标准方法OracleDBManager
和 SqlDBManager
类?标准方法非常重要,因为我不想让使用这些辅助类的代码知道它们连接的是 Oracle 还是 Sql Server。
我确实考虑过使用 ORM 解决方案,例如 Entity Framework 4 和 nHibernate,但性能影响太大。由于我将运行简单的查询,因此 PL-SQL 和 TSQL 之间的查询语法差异无关紧要。
任何输入和想法将不胜感激。谢谢
最佳答案
为什么不让你的静态方法私有(private),将类包装在一个接口(interface)中以支持 MS-SQL/Oracle,并在各自的接口(interface)中调用私有(private)静态方法?
例如:
public interface ISqlDbManager
{
void SaveOrder(Order o);
void FindOrderById(int orderId);
}
public class SqlServerDbManager : ISqlDbManager
{
private static void RunSql(String pSql, DBParamsHelper pDBParams, String pConnStringConfigName)
{
// implement as you did above
}
public void FindOrderById(int orderId)
{
// create SQL, call private "RunSql" method.
}
}
对另一个实现 (OracleDbManager) 执行相同的操作。
将其私有(private)化是有意义的,因为消费者不应该关心底层持久性机制是如何工作的。
这也将使单元测试更容易 - 创建一个“MockDbManager”类,其中私有(private)静态方法在内存列表上执行基本的 LINQ 操作。
附带说明,我会强烈建议使用存储过程,而不是手动构建 sql 命令。更适合查询计划缓存/优化。
关于数据库助手类的 C# 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5111792/