Вам уже нужны параметры независимо от того, внедряете ли вы хранимые процедуры.
Прямо сейчас ваш код может быть вызван с запросом, подобным SELECT * FROM Table WHERE ID = @ID
, в этом случае вам уже нужно передать Dictionary<string,object> params
. Заставьте свой код заполнить коллекцию параметров уже имеющейся у вас команды и проверьте ее, прежде чем беспокоиться о хранимых процедурах.
Как только это сработает, вы должны просто создать перегрузку, которая принимает bool, который говорит, что это хранимая процедура, а затем использовать ее для установки свойства CommandType команды.
Редактировать: Вот как я бы это изобразил
Шаг 1: обобщить обновление
В методе Update нет ничего особенного, что не позволяет использовать его для других операций, не связанных с запросом, кроме имени. Итак:
/// <summary>
/// Executes Update statements in the database.
/// </summary>
/// <param name="sql">Sql statement.</param>
/// <returns>Number of rows affected.</returns>
public static int Update(string sql)
{
return NonQuery(sql);
}
public static int NonQuery(string sql)
{
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
using (DbCommand command = factory.CreateCommand())
{
command.Connection = connection;
command.CommandText = sql;
connection.Open();
return command.ExecuteNonQuery();
}
}
}
Шаг 2: А как насчет параметров?
Ваш текущий код не может даже обрабатывать запросы UPDATE, которые используют параметры, поэтому давайте начнем исправлять это. Во-первых, убедитесь, что он все еще работает, если параметры не указаны:
public static int NonQuery(string sql)
{
Dictionary<string, object> parameters = null;
if (parameters == null)
{
parameters = new Dictionary<string, object>();
}
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
using (DbCommand command = factory.CreateCommand())
{
command.Connection = connection;
command.CommandText = sql;
foreach (KeyValuePair<string, object> p in parameters)
{
var parameter = command.CreateParameter();
parameter.ParameterName = p.Key;
parameter.Value = p.Value;
command.Parameters.Add(parameter);
}
connection.Open();
return command.ExecuteNonQuery();
}
}
}
Как только это сработает, выдвиньте параметров в качестве параметра. Это не влияет на существующие абоненты Update
:
/// <summary>
/// Executes Update statements in the database.
/// </summary>
/// <param name="sql">Sql statement.</param>
/// <returns>Number of rows affected.</returns>
public static int Update(string sql)
{
return NonQuery(sql, null);
}
public static int NonQuery(string sql, Dictionary<string, object> parameters)
На этом этапе протестируйте NonQuery с параметризованным запросом. Как только это сработает, создайте перегрузку Update, которая принимает параметры:
/// <summary>
/// Executes Update statements in the database.
/// </summary>
/// <param name="sql">Sql statement.</param>
/// <returns>Number of rows affected.</returns>
public static int Update(string sql)
{
return NonQuery(sql, null);
}
/// <summary>
/// Executes Update statements in the database.
/// </summary>
/// <param name="sql">Sql statement.</param>
/// <param name="parameters">Name/value dictionary of parameters</param>
/// <returns>Number of rows affected.</returns>
public static int Update(string sql, Dictionary<string, object> parameters)
{
return NonQuery(sql, parameters);
}
Шаг 3: Принять хранимые процедуры на счет
Существует небольшая разница в том, как будут обрабатываться хранимые процедуры. То, что вы уже получили, подразумевается следующим образом:
using (DbCommand command = factory.CreateCommand())
{
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
Итак, возьмите CommandType.Text и сделайте его параметром перегрузки:
public static int NonQuery(string sql, Dictionary<string, object> parameters)
{
return NonQuery(sql, CommandType.Text, parameters);
}
public static int NonQuery(string sql, CommandType commandType, Dictionary<string, object> parameters)
Наконец, если хотите, обновите Update
:
/// <summary>
/// Executes Update statements in the database.
/// </summary>
/// <param name="sql">Sql statement.</param>
/// <param name="parameters">Name/value dictionary of parameters</param>
/// <returns>Number of rows affected.</returns>
public static int Update(string sql, Dictionary<string, object> parameters)
{
return Update(sql, CommandType.Text, parameters);
}
/// <summary>
/// Executes Update statements in the database.
/// </summary>
/// <param name="sql">Sql statement.</param>
/// <param name="commandType">CommandType.Text or CommandType.StoredProcedure</param>
/// <param name="parameters">Name/value dictionary of parameters</param>
/// <returns>Number of rows affected.</returns>
public static int Update(string sql, CommandType commandType, Dictionary<string, object> parameters)
{
return NonQuery(sql, parameters);
}
Конечно, в качестве заключительного упражнения для читателя вы можете заменить все ваши вызовы на обновление вызовами NonQuery и полностью избавиться от обновления.
Конечно, этот простой метод не обрабатывает выходные параметры или ситуации, когда необходимо указать DbType параметра. Для этого вам нужно принять коллекцию ParameterCollection некоторого вида.