这段代码会浪费资源吗?

时间:2016-03-12 13:16:20

标签: c# asp.net c#-4.0 gridview

我正在使用gridview来选择多个记录,然后在它上面循环以将每个记录ID单独发送到数据库并更新它但是我找不到很好的实现方法,因为它每次打开和关闭连接那么好的方法是什么?

foreach (GridViewRow r in grdViewLastHearingDates.Rows)
    {
        int CaseHearingID = Convert.ToInt32(r.Cells[0].Text);
        CheckBox chkBox = r.FindControl("chkBoxIsConveyed") as CheckBox;

        TextBox txtboxConvenienceRemarks = r.FindControl("txtBoxConvenienceRemarks") as TextBox;
        string ConvenienceRemarks = txtboxConvenienceRemarks.Text;

        MngCaseHearings.UpdateCasesIsConveyed(CaseHearingID, ConvenienceRemarks, chkBox.Checked);
    }

MngCaseHearings.UpdateCasesIsConveyed每次都会发送并执行此代码以更新每个ID。请查看并提出建议

    public Boolean UpdateCasesIsConveyed(int CaseHearingID, string ConvenienceRemarks, bool IsConveyed)
    {

        try
        {
            SqlCommand SqlCom = new SqlCommand("UpdateCasesIsConveyed", DatabaseConnection.OpenConnection());
            SqlCom.CommandType = CommandType.StoredProcedure;
            SqlCom.Parameters.AddWithValue("@pk_CaseHearings_ID ", CaseHearingID);
            SqlCom.Parameters.AddWithValue("@IsConveyed", IsConveyed);
            SqlCom.Parameters.AddWithValue("@ConvenienceRemarks", ConvenienceRemarks);

            SqlParameter SqlParamReturnStatus = new SqlParameter("@ReturnStatus", SqlDbType.Bit);
            SqlCom.Parameters.Add(SqlParamReturnStatus);
            SqlParamReturnStatus.Direction = ParameterDirection.Output;

            SqlParameter SqlParamReturnStatusMessage = new SqlParameter("@ReturnStatusMessage", SqlDbType.VarChar, -1);
            SqlCom.Parameters.Add(SqlParamReturnStatusMessage);
            SqlParamReturnStatusMessage.Direction = ParameterDirection.Output;

            SqlCom.ExecuteNonQuery();

            string ReturnStatusMessage = Convert.ToString(SqlParamReturnStatusMessage);
            Boolean ReturnStatus = Convert.ToBoolean(SqlParamReturnStatus.Value);

            return ReturnStatus;
        }
 catch (Exception)
            {

                throw;
            }

            finally 
            {
                DatabaseConnection.CloseConnection();
            }
如果有任何好的解决方法,这会浪费资源吗?

1 个答案:

答案 0 :(得分:0)

由于SqlConnectionSqlCommand对象都实现了IDisposable,因此您应该在完成后将其丢弃。最简单的方法是通过using语句:

using (var conn = DatabaseConnection.OpenConnection())
using (var SqlCom = new SqlCommand("UpdateCasesIsConveyed", conn))
{
    // setup and execute the SP, can return from in here
}

这将确保在您完成后正确关闭对象使用的资源。虽然这不是必需的 - 当垃圾收集器销毁对象时将调用Dispose方法 - 它将确保您不会超过必要时保持打开数据库对象。根据调用此频率的频率,最终可能会导致SQL服务器上的资源短缺,过多的句柄使用等。

一般来说,实施IDisposable的任何内容都应尽快处理。

(抱歉,错过了问题的循环部分)

这种类型的创建/销毁循环适用于单个操作,但在用于更新大量记录时会变得浪费。我会把循环放在代码的中间,而不是从外面重复调用这段代码。

我将创建一个包含SP参数的记录类或结构,并将该记录类的IEnumerable传递给您的更新方法。这样,您可以进行一次设置,处理所有更新,然后在完成所有更改后拆除数据库对象。也抛出一个事务,如果其中一个记录失败,你可以撤消所有事务。

类似的东西:

public struct UpdateCaseConveyanceRec
{
    public int CaseHearingID;
    public string ConvenienceRemarks;
    public bool IsConveyed;
}

public bool UpdateCasesIsConveyed(IEnumerable<UpdateCaseConveyanceRec> uopdates)
{
    using (SqlConnection conn = DatabaseConnection.OpenConnection())
    using (SqlCommand cmd = new SqlCommand("UpdateCasesIsConveyed", conn))
    using (SqlTransaction trans = conn.BeginTransaction("UpdateCasesIsConveyed"))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        var pID = cmd.Parameters.Add("@pk_CaseHearings_ID", SqlDbType.Int);
        var pConveyed = cmd.Parameters.Add("@IsConveyed", SqlDbType.Bit);
        var pRemarks = cmd.Parameters.Add("@ConvenienceRemarks", SqlDbType.VarChar, -1);

        var retStatus = cmd.Parameters.Add("@ReturnStatus", SqlDbType.Bit);
        retStatus.Direction = ParameterDirection.Output;

        var retStatusMsg = cmd.Parameters.Add("@ReturnStatusMessage", SqlDbType.VarChar, -1);
        retStatusMsg.Direction = ParameterDirection.Output;

        try
        {
            foreach (var row in updates)
            {
                pID.Value = row.CaseHearingID;
                pConveyed.Value = row.IsConveyed;
                pRemarks.Value = row.ConvenienceRemarks;

                cmd.ExecuteNonQuery();

                if (!Convert.ToBoolean(retStatus))
                {
                    trans.Rollback();
                    return false;
                }
            }

            trans.Commit();
        }
        catch ()
        {
            trans.Rollback();
            throw;
        }

        return true;
    }
}

然后,您可以使用LINQ to Objects查询提供该信息:

var source = 
    from r in grdViewLastHearingDates.Rows.OfType<GridViewRow>()
    select new UpdateCaseConveyanceRec
    {
        CaseHearingID = Convert.ToInt32(r.Cells[0].Text),
        ConvenienceRemarks = (r.FindControl("txtBoxConvenienceRemarks") as TextBox).Text;
        IsConveyed = (r.FindControl("chkBoxIsConveyed") as CheckBox).Checked
    };

bool updated = UpdateCasesIsConveyed(source);