簡體   English   中英

C#數據庫助手類的設計模式

[英]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虛方法,因此在那里使用不多。 我考慮過一些單例實現,所以我不必創建類,但是我會在多線程訪問上遇到麻煩。
什么是最好的設計模式,所以我可以在多線程場景(非常重要)上有很好的性能,沒有太多工作編碼生產力(不必創建很多類),並且有OracleDBManagerSqlDBManager的標准方法班? 標准方法非常重要,因為我不希望使用這些幫助程序類的代碼知道它們是否連接到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM