首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这段代码会浪费资源吗?

这段代码会浪费资源吗?
EN

Stack Overflow用户
提问于 2016-03-12 21:16:20
回答 1查看 51关注 0票数 1

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

代码语言:javascript
复制
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);
    }

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

代码语言:javascript
复制
    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();
            }

这会浪费资源,所以有没有好的工作呢?

EN

回答 1

Stack Overflow用户

发布于 2016-03-12 23:42:31

由于SqlConnectionSqlCommand对象都实现了IDisposable,因此您可能应该在完成后处理掉它们。最简单的方法是通过using语句:

代码语言:javascript
复制
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传递给您的更新方法。通过这种方式,您可以进行一次设置,处理所有更新,然后在完成所有更改后销毁数据库对象。还可以抛出一个事务,这样如果其中一个记录失败,就可以撤消所有事务。

类似于:

代码语言:javascript
复制
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查询将其提供给它:

代码语言:javascript
复制
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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35958106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档