我使用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);
}每次更新每个ID时,MngCaseHearings.UpdateCasesIsConveyed都会发送并执行此代码。请查看并提供建议
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();
}这会浪费资源,所以有没有好的工作呢?
发布于 2016-03-12 23:42:31
由于SqlConnection和SqlCommand对象都实现了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);https://stackoverflow.com/questions/35958106
复制相似问题