使用SqlParameter

时间:2018-11-06 22:31:12

标签: c# sql asp.net-core

我知道如何将一个参数传递给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 :(得分:1)

我还建议您使用Dapper而不是重新发明轮子-但如果由于某些原因您不能这样做,我将方法签名更改为接受params SqlParameter[] parameters而不是params object[] parameters-然后您方法中需要做的是command.Parameters.AddRange(parameters);

正如马克·格雷夫(Marc Gravel)在其评论中所写-如果仅使用object[],则命名参数将是最大的问题。

答案 1 :(得分:0)

这是我编写的一种比较两个不同日期的值的方法:

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(这是我在撰写本文时所需要的)。您可以使用this,并进行修改以使其更适合您的需求。


您要使用的是:

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)。

答案 2 :(得分:0)

我以前已经按照这些思路完成了实现。

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,这样可以节省很多时间。但是我发现尝试以上述类型的解决方案重用的问题经常会造成一些紧密的耦合。

通过这种方法,您会将有关查询的特定信息推送到其他位置,从而将逻辑直接从存储库中分离出来,并紧密耦合到另一个依赖项和知识。