Rene
Rene

Reputation: 105

Optimize usage of SqlCommand

I execute a stored procedure from C# like this:

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

ExeSQLParamByDateTime method is too large:

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
}

There is no way to optimize this? I just checking for good practices, as you can see I send param DataTable to execute sql TableType and in addition send parameters, but I don't found anything similar like this. Help is appreciated. regards

Upvotes: 0

Views: 262

Answers (1)

Joel Coehoorn
Joel Coehoorn

Reputation: 415921

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;
}

Upvotes: 3

Related Questions