我正在使用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();
}
如果有任何好的解决方法,这会浪费资源吗?
答案 0 :(得分:0)
由于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);