我想为mysql和mssql编写自定义SQL代码(可能更晚一些)。
var dbSystem = "mssql";
if ("mssql" == dbSystem) {
var mssqlConn = new SqlConnection(mssqlConnString);
new SqlCommand("CREATE TABLE t1 (c1 in NOT NULL PRIMARY KEY IDENTITY(1,1), c2 int)", mssqlConn).ExecuteNonQuery();
} else {
var mysqlConn = new MySqlConnection(mysqlConnString);
new SqlCommand("CREATE TABLE t1 (c1 in NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 int)", mssqlConn).ExecuteNonQuery();
}
问题从这里开始。我想在if语句之前通过接口或abstract-class声明连接。但似乎不可能,因为命令类明确要求特定的SqlConnection或MySqlConnection。
如果您想执行像SELECT c1 form t1 where c2 = @value
这样的简单命令,问题就会变得更糟。因为你必须像上面那样做。
是否有API提供如下工作流程:
IDbConnection conn; // initialized by SqlConnection or MySqlConnection, etc.
IDbCommand cmd = new DbCommand("SELECT c1 form t1 where c2 = @value", conn);
cmd.Parameters.Add("@value", Type.Int);
问题:
答案 0 :(得分:6)
可行的方法是使用DbProviderFactories.GetFactory(String)来检索DbProviderFactory对象。
使用DbProviderFactory.CreateConnection()会为您提供DbConnection个对象。
设置此DbConnection对象的ConnectionString属性并调用Open()方法将导致打开与所需数据库的连接。
使用DbConnection.CreateCommand()会根据需要为您提供DbCommand个对象。
要使用参数化查询,您可以使用DbCommand.CreateParameter()来返回DbParameter个对象。
示例:
// MySQL
DbProviderFactory factory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
// MS-SQL
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
private void Query(String query,Dictionary<String,object> namesAndValues, System.Data.CommandType commandType)
{
String connectionString = ConfigurationManager.ConnectionStrings["yourConnectionString"];
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = query;
command.CommandType = commandType;
AddParameters(command, namesAndValues);
using (DbDataReader reader=command.ExecuteReader())
{
while (reader.Read())
{
//
}
}
}
}
}
private void AddParameters(DbCommand command, Dictionary<String, object> namesAndValues)
{
String factoryName = factory.GetType().Name;
DbParameter para;
foreach (String key in namesAndValues.Keys)
{
para = command.CreateParameter();
switch (factoryName)
{
case "SqlClientFactory":
para.ParameterName = "@" + key;
break;
case "OracleClientFactory":
para.ParameterName = ":" + key;
break;
case "OleDbFactory":
para.ParameterName = "?";
break;
case "MySqlClientFactory":
para.ParameterName = "?" + key;
break;
}
para.Value = namesAndValues[key];
command.Parameters.Add(para);
}
}
答案 1 :(得分:2)
您总是可以使用DbProviderFactory
来抽象具体的驱动程序实现。 http://msdn.microsoft.com/de-de/library/system.data.common.dbproviderfactory(v=vs.110).aspx
对于特定于数据库的SQL命令,您还需要创建某种抽象。 喜欢
interface IQueryBuilder{
string BuildCreateTableQuery();
}
class MySqlQueryBuilder : IQueryBuilder {
}
class SqlQueryBuilder : IQueryBuilder {
}
class OracleQueryBulder : IQueryBuilder{
}