Передать несколько параметров с SqlParameter - PullRequest
0 голосов
/ 07 ноября 2018

Я знаю, как передать один параметр в SQL-запрос, но я хочу создать функцию для передачи нескольких параметров, которые будут иметь разный тип, и здесь я застрял.

public List<T> RawSql<T>(string query,  params object[] parameters)
{
    var command = context.Database.GetDbConnection().CreateCommand();

    command.CommandText = query;
    command.CommandType = CommandType.Text;

    SqlParameter parameter = new SqlParameter();
    parameter.ParameterName = "@bookId";
    parameter.SqlDbType = SqlDbType.Int;

    parameter.Value = parameters[0];

    command.Parameters.Add(parameter);

    var result = command.ExecuteReader())

    return result;
}

Использование:

var rows = helper.RawSql("myStoreProc @bookId", x=> new Book { Id = (bool)x[0] }, bookId);

Но как я могу изменить функцию RawSql для передачи нескольких параметров, например:

var rows = helper.RawSql("myStoreProc @bookId, @authorName", x=> new Book { Id = (bool)x[0] }, bookId, authorName);

Ответы [ 3 ]

0 голосов
/ 07 ноября 2018

Вот метод, который я написал для сравнения значений двух разных дней:

public DataTable sqlToDTCompare(string conStr, string stpName, DateTime startDate, DateTime endDate, int percent)
    {
        //receives connection string and stored procedure name
        //then returns populated data table
        DataTable dt = new DataTable();

        using (var con = new SqlConnection(conStr))
        using (var cmd = new SqlCommand(stpName, con))
        using (var da = new SqlDataAdapter(cmd))
        {
            cmd.Parameters.Add("@StartDate", SqlDbType.Date).Value = startDate;
            cmd.Parameters.Add("@EndDate", SqlDbType.Date).Value = endDate;
            cmd.Parameters.Add("@Percent", SqlDbType.Int).Value = percent;
            cmd.CommandType = CommandType.StoredProcedure;
            da.Fill(dt);
        }

        return dt;
    }

Этот метод затем возвращает эти данные в DataTable (это было то, что мне было нужно во время написания). Вы могли бы использовать это, с изменениями, чтобы лучше соответствовать вашим потребностям.


То, что вы хотите использовать, является чем-то вроде:

SqlCommand.Parameters.Add("@Param1", SqlDbType.Type).Value = param1;
SqlCommand.Parameters.Add("@Param2", SqlDbType.Type).Value = param2;
SqlCommand.Parameters.Add("@Param3", SqlDbType.Type).Value = param3;
.....

Где .Type в SqlDbType.Type можно изменить для соответствия любому необходимому типу данных SQL (например, SqlDbType.Date).

0 голосов
/ 07 ноября 2018

Я ранее делал реализации по этим направлениям.

public IEnumerable<SampleModel> RetrieveSampleByFilter(string query, params SqlParameter[] parameters)
{
     using(var connection = new SqlConnection(dbConnection))
          using(var command = new SqlCommand(query, connection))
          {
              connection.Open();
              if(parameters.Length > 0)
                  foreach(var parameter in parameters)
                       command.Parameters.Add(parameter);

                       // Could also do, instead of loop:
                       // command.Parameters.AddRange(parameters);

              using(var reader = command.ExecuteReader())
                   while(reader != null)
                        yield return new Sample()
                        {
                             Id = reader["Id"],
                             ...
                        }                   
          }
}

Я на самом деле написал метод расширения для чтения значений, возвращаемых обратно в мой объект, но это позволяет вам передавать запрос и ряд параметров, чтобы просто вернуть ваш объект.

Я бы посмотрел в Dapper, экономит много времени. Но я нахожу, что проблема с попыткой повторного использования с вышеупомянутым типом решения часто создает тесную связь.

Используя этот подход, вы помещаете конкретную информацию о вашем запросе в другое место, которая отделяет логику непосредственно из хранилища и тесно связывает ее с другой зависимостью и знаниями.

0 голосов
/ 07 ноября 2018

Я бы также предложил использовать Dapper вместо того, чтобы заново изобретать колесо - но если вы не можете по какой-то причине, я бы изменил сигнатуру метода, чтобы принимать params SqlParameter[] parameters вместо params object[] parameters - и затем все, что вам нужно сделать в метод command.Parameters.AddRange(parameters);.

Как писал Марк Гравел в своем комментарии, наименование параметров будет самой большой проблемой, если вы просто используете object[].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...