簡體   English   中英

C#中的多數據庫支持

[英]Multiple database support in C#

我的應用程序需要支持多個數據庫。 目前,它支持Postgres,我現在正在添加對Orcle的支持,並且可能在未來幾天內成為SqlServer。

在詢問任何問題之前,請查看代碼。

IDbParser:

public interface IDbParser
{
    IDbConnection GetDbConnection(string ServerName, string DbPortNumber, string Username, string Password, string DatabaseName);
    IDbCommand GetDbCommand(string query, IDbConnection sqlConnection);
    IDataParameter CreateParameter(string key, object value);
    string GetDbQuery(DbQueries query);
}

OracleDbParser:

public class OracleParser : IDbParser
{
    #region >>> Queries
    private string SELECTGROUPSESSIONS = "....";
    ........
    #endregion

    public IDbCommand GetDbCommand(string query, IDbConnection sqlConnection)
    {
        var command = new OracleCommand();
        command.CommandText = query;
        command.Connection = (OracleConnection)sqlConnection;
        command.CommandType = CommandType.Text;
        command.CommandTimeout = 300;
        return command;
    }

    public IDataParameter CreateParameter(string key, object value)
    {
        return new OracleParameter(key, value);
    }        

    public IDbConnection GetDbConnection(string ServerName, string DbPortNumber, string Username, string Password, string DatabaseName)
    {
        connString = String.Format("Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL=TCP)(HOST={0})(PORT={1})))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={2}))); Connection Timeout=60; User Id={3};Password={4};",
                                                ServerName, DbPortNumber, DatabaseName, Username, Password);
        return new OracleConnection(connString);
    }

    public string GetDbQuery(DbQueries query)
    {
        switch (query)
        {                
            case DbQueries.SELECTGROUPSESSIONS:
                return SELECTGROUPSESSIONS;
            ................
            ..............
            default:
                return String.Empty;
        }
    }
}

同樣, Postgres有解析器

public class PostgresParser : IDbParser
{
    #region >>> Queries
    private string SELECTGROUPSESSIONS = "....";
    ........
    #endregion

   public IDbCommand GetDbCommand(string query, IDbConnection sqlConnection)
    {
        var command = new NpgsqlCommand();
        command.CommandText = query;
        command.Connection = (NpgsqlConnection)sqlConnection;
        command.CommandType = CommandType.Text;
        return command;
    }

    public IDataParameter CreateParameter(string key, object value)
    {
        return new NpgsqlParameter(key, value);
    }       

    public IDbConnection GetDbConnection(string ServerName, string DbPortNumber, string Username, string Password, string DatabaseName)
    {
        string connString = String.Format("Server={0};Port={1};Timeout=60;CommandTimeout=300;" +
                                            "User Id={2};Password={3};Database={4};",
                                            ServerName, DbPortNumber, Username, Password, DatabaseName);
        return new NpgsqlConnection(connString);
    }


    public string GetDbQuery(DbQueries query)
    {
        switch (query)
        {                
            case DbQueries.SELECTGROUPSESSIONS:
                return SELECTGROUPSESSIONS;
            ................
            ..............
            default:
                return String.Empty;
        }
    }
}

DatabaseParserFactory:

 public class DatabaseParserFactory
{
    public static IDbParser GetDbParser(string dbType)
    {
        CUCMDbType dbTypeName;
        Enum.TryParse(dbType.ToLower(), out dbTypeName);
        switch (dbTypeName)
        {
            case CUCMDbType.oracle:
                return new OracleParser();
            case CUCMDbType.postgres:
                return new PostgresParser();
            default:
                return new PostgresParser();
        }
    }
}

查詢執行:

 public void Query(string queryStatement, DbParameterColl parameters, Action<IDataReader> processReader)
    {
        using (SqlConnection)
        {
            IDbCommand selectCommand = null;                
            selectCommand = _factory.GetDbCommand(queryStatement, SqlConnection);                     
            selectCommand.Parameters.Clear();

            using (selectCommand)
            {
                if (parameters != null)
                {
                    foreach (var param in parameters)
                    {
                        selectCommand.Parameters.Add(_factory.CreateParameter(param.Key, param.Value));                           
                    }
                }

                try
                {                 
                    using (var reader = selectCommand.ExecuteReader())
                    {
                        processReader(reader);
                    }

                }
                catch (Exception ex)
                {
                    Logger.DebugFormat("Unable to execute the query. Query : {0} . Exception: {1}", queryStatement, ex);
                    Debug.WriteLine("\n\n>> Error on executing reader. Exception :\n " + ex);
                }
            }
        }
    }

僅供參考:只有SELECT查詢而沒有其他命令。

我將參數的值作為對象傳遞。 那么,目前分配參數和執行查詢沒有問題。 但是在大多數博客和stackoverflow中,我可以看到人們一直在建議指定輸入方向,最具體的是輸入類型/ DbType 我需要指定DbType嗎? 目前,我的代碼運行正常,沒有錯誤。 但我擔心,它可能會在生產中崩潰。

而且我無法控制參數的類型,它可以是任何東西。 那么你們有什么建議呢? 或者有更好的方法嗎?

首先,您應該看看DbProviderFactories - 您的大多數代碼都復制了已有的標准功能。 請注意,它在.NET Core中尚不可用(但將會是)。

關於您的問題,通常您不需要指定parmeter方向 - 它被假定為默認值。 數據庫驅動程序通常可以從您為參數分配的CLR值推斷數據庫類型,但最好明確指定DbType以確保。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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