【问题标题】:Optimize usage of SqlCommand优化SqlCommand的使用
【发布时间】:2018-08-23 03:04:33
【问题描述】:

我从 C# 执行一个存储过程,如下所示:

medianOfProjects = db.ExeSQLParamByDateTime("usp_TaskStatistics_Median_Calculation", parameters, "@TaskTypeTableType", 1, startDate, endDate
                     unitNumberFrom, unitNumberTo, unitNumberBldgsSegsFrom, unitNumberBldgsSegsTo, unitNumberSqrFrom, unitNumberSqrTo, unitNumberWoodStoriesFrom,
                unitNumberWoodStoriesTo, currentRegionKey);

ExeSQLParamByDateTime 方法过大:

public DataTable ExeSQLParamByDateTime(string sprocName, DataTable paramArray, string tableTypeName, int LegacyKey, DateTime startingDate, DateTime endingDate,
            int unitNumberFrom, int unitNumberTo, int BldgSegsFrom, int BldgSegsFromTo, int SquareFootageFrom, int SquareFootageTo, int WoodStoriesFrom,
            int WoodStoriesTo, int StatusKey)
{
   SqlCommand cmd = new SqlCommand(sprocName, this.dbconn);

   var startDate = startingDate.Date;
   var endDate = endingDate.Date;

   cmd.CommandType = CommandType.StoredProcedure;

   cmd.Parameters.Add(new SqlParameter(tableTypeName, SqlDbType.Structured));
   cmd.Parameters[tableTypeName].Value = paramArray;

   cmd.CommandType = CommandType.StoredProcedure;
   cmd.Parameters.Add(new SqlParameter("@LegacyKey", SqlDbType.Int));
   cmd.Parameters["@LegacyKey"].Value = LegacyKey;

   cmd.Parameters.Add(new SqlParameter("@StartingDate", SqlDbType.DateTime));
   cmd.Parameters["@StartingDate"].Value = startDate;

   cmd.Parameters.Add(new SqlParameter("@EndingDate", SqlDbType.DateTime));
   cmd.Parameters["@EndingDate"].Value = endDate;

   cmd.Parameters.Add(new SqlParameter("@UnitNumberFrom", SqlDbType.Int));
   cmd.Parameters["@UnitNumberFrom"].Value = unitNumberFrom;

   cmd.Parameters.Add(new SqlParameter("@UnitNumberTo", SqlDbType.Int));
   cmd.Parameters["@UnitNumberTo"].Value = unitNumberTo;

   //etc
   //etc
}

有没有办法优化这个?我只是检查好的做法,如您所见,我发送参数 DataTable 以执行 sql TableType 并发送参数,但我没有找到类似的东西。帮助表示赞赏。问候

【问题讨论】:

  • 优化是什么意思。具体
  • 我认为他只是意味着减少代码量。每个参数两行(包括空格在内 3 行)+ 很多参数会变得乏味。
  • 如果您使用像 Dapper 或 PetaPoco 这样的微型 ORM,它将减少相当多的此类样板。

标签: c# sql-server stored-procedures sqlcommand


【解决方案1】:
public DataTable ExeSQLParamByDateTime(string sprocName, DataTable paramArray, string tableTypeName, int LegacyKey, DateTime startingDate, DateTime endingDate,
        int unitNumberFrom, int unitNumberTo, int BldgSegsFrom, int BldgSegsFromTo, int SquareFootageFrom, int SquareFootageTo, int WoodStoriesFrom,
        int WoodStoriesTo, int StatusKey
        )
{
    var result = new DataTable();

    //Not good to re-use the same connection object.
    // ADO.Net is designed to use connection pooling, which means you want a new connection each time.
    // Instead, just re-use the connection string
    using (var cn = new SqlConnection(this.dbconn.ConnectionString))
    using (var cmd = new SqlCommand(sprocName, cn))
    {
        cmd.CommandType = CommandType.StoredProcedure; //only need to do this once

        //Most parameters can get down to a single line
        cmd.Parameters.Add(tableTypeName, SqlDbType.Structured).Value = paramArray;
        cmd.Parameters.Add("@LegacyKey", SqlDbType.Int).Value = LegacyKey;
        cmd.Parameters.Add("@StartingDate", SqlDbType.DateTime).Value = startingDate.Date;
        cmd.Parameters.Add("@EndingDate", SqlDbType.DateTime).Value = endingDate.Date;
        cmd.Parameters.Add("@UnitNumberFrom", SqlDbType.Int).Value = unitNumberFrom;
        cmd.Parameters.Add("@UnitNumberTo", SqlDbType.Int).Value = unitNumberTo;
        //etc
        //etc

        //you can also handle parameters with size scopes this way:
        cmd.Parameters.Add("@FakeParam", SqlDbType.Decimal, 5, 2).Value = 123.45;
        cmd.Parameters.Add("@AlsoFake", SqlDbType.NVarChar, 30).Value = "Hello World";

        cn.Open(); // wait as long as possible to open the connection
        using (var rdr = cmd.ExecuteReader())
        {
            result.Load(rdr);
            rdr.Close();
        }
    } //using block handles closing the connection, even if an exception is thrown
    return result;
}

【讨论】:

  • using 消除了关闭阅读器的需要。 Dispose 终将关闭读者。
  • The documentation for SqlDataReader doesn't make the same claim for the reader. msdn.microsoft.com/en-us/library/… 状态 The base implementation of this method calls the Close method if disposing is set to true.
  • 嗯,这是一个相当新的变化 :) 欢迎来到编程,您认为自己知道的一切都只是过去某个时间点的快照。
猜你喜欢
  • 2013-03-07
  • 2011-05-26
  • 2011-01-27
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
相关资源
最近更新 更多