![](/img/trans.png)
[英]Best way to apply design pattern for a given Database design in C# Classes
[英]C# Design Pattern for Database Helper classes
我正在设计一个将由数百个客户端调用的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的支持。 我最初的想法是声明一个接口,并让我现有的SqlDBManager
实现它,然后开发一个实现相同接口的OracleDBManager
。 问题是我的类是静态的,静态类不能实现接口。 我希望我的助手类保持静态,它更实用,而且每次我需要运行查询时都不必创建新对象。 我还想过使用类继承,但是我不能使用statis虚方法,因此在那里使用不多。 我考虑过一些单例实现,所以我不必创建类,但是我会在多线程访问上遇到麻烦。
什么是最好的设计模式,所以我可以在多线程场景(非常重要)上有很好的性能,没有太多工作编码生产力(不必创建很多类),并且有OracleDBManager
和SqlDBManager
的标准方法班? 标准方法非常重要,因为我不希望使用这些帮助程序类的代码知道它们是否连接到Oracle或Sql Server。
我确实考虑过使用ORM解决方案,例如Entity Framework 4和nHibernate,但性能影响太大了。 由于我将运行简单查询,因此PL-SQL和TSQL之间的查询语法差异无关紧要。
任何意见和想法将不胜感激。 TKS
为什么不将静态方法设为私有 ,将类包装在接口中以支持MS-SQL / Oracle,并在各自的接口中调用私有静态方法?
例如:
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)执行相同的操作。
将它私有化是有意义的,因为消费者不应该关心底层持久性机制如何工作。
这也将使单元测试更容易 - 创建一个“MockDbManager”类,其中私有静态方法在内存列表中执行基本的LINQ操作。
另外,我强烈建议使用存储过程,而不是手动构建sql命令。 更适合查询计划缓存/优化。
接口是正确的方向,但正如您所指出的,您不能让静态类实现接口。 我理解想要最小化对象创建的大惊小怪,但是为了拥有两个不同的数据库类,这可能在某种程度上是必要的。
我建议的解决方案是多方面的。 首先是一个具有类似于上面列出的签名的界面:
public Interface IDbManager {
void RunSql(String pSql, DBParamsHelper pDBParams, String pConnStringConfigName)
}
这可以在SQL和Oracle特定版本中实现,您已经拥有SQL版本,只需将其设置为非静态并实现接口即可。
现在尝试一个数据库工厂,可能如下所示:
public static class DbFactory {
public static IDbManager CreateDb(DbType type) {
select (type) {
case DbType.Sql:
return new SqlDbManager();
break;
case DbType.Sql:
return new OracleDbManager();
break;
}
}
}
然后你应该能够做到这样的事情:
var db = DbFactory.CreateDb(DbType.Sql);
db.RunQuery(...);
此代码未经测试,但希望您能得到这个想法。 我为我的一个项目使用类似的解决方案,我需要从不同的数据存储中获取数据。 战略和工厂模式简化了这一过程。
希望有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.