[英]Multiple database support in C#
My application need to support multiple databases. 我的应用程序需要支持多个数据库。 Currently, it supports Postgres now I am adding support for Orcle and may be SqlServer in upcoming days.
目前,它支持Postgres,我现在正在添加对Orcle的支持,并且可能在未来几天内成为SqlServer。
Before asking any question lets look at codes. 在询问任何问题之前,请查看代码。
IDbParser : 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 : 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;
}
}
}
Similarly, there is parser for Postgres : 同样, 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: 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();
}
}
}
Query execution : 查询执行:
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);
}
}
}
}
FYI: There will only be SELECT queries and no other commands. 仅供参考:只有SELECT查询而没有其他命令。
I am passing parameter's value as an object. 我将参数的值作为对象传递。 Well, currently there is no problem assigning the parameters and executing the query.
那么,目前分配参数和执行查询没有问题。 But in most of the blogs and in stackoverflow I could see that people have been suggesting to specify the Input direction, and most specifically Input type/DbType .
但是在大多数博客和stackoverflow中,我可以看到人们一直在建议指定输入方向,最具体的是输入类型/ DbType 。 Do I need to specify DbType ?
我需要指定DbType吗? Currently, my code runs fine with no errors.
目前,我的代码运行正常,没有错误。 But I am afraid, it might break down in production.
但我担心,它可能会在生产中崩溃。
Moreover I have no control over the type of parameter, it could be anything. 而且我无法控制参数的类型,它可以是任何东西。 So what do you guys suggest?
那么你们有什么建议呢? Or is there any better approach of doing this ?
或者有更好的方法吗?
First, you should take a look at DbProviderFactories - most of your code duplicates that already-existing standard functionality. 首先,您应该看看DbProviderFactories - 您的大多数代码都复制了已有的标准功能。 Note that it is not yet available in .NET Core (but will be).
请注意,它在.NET Core中尚不可用(但将会是)。
Regarding your question, in general you don't need to specify the parmeter direction - it's assumed to be the default. 关于您的问题,通常您不需要指定parmeter方向 - 它被假定为默认值。 Database drivers can typically infer the database type from the CLR value you assign to a parameter, but it's a good idea to explicitly specify DbType just to be sure.
数据库驱动程序通常可以从您为参数分配的CLR值推断数据库类型,但最好明确指定DbType以确保。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.