【发布时间】:2021-01-14 17:06:03
【问题描述】:
public int UpdateAmount(List<MyTable> myBizObjList)
{
SqlTransaction sqltxn;
DbClass db = new DbClass();
SqlConnection cs;
cs = db.GetConnection();
string commandText = @"Update MyTable Set amt = @amt where empno = @empno and mydate = @mydate";
int x = myBizObjList.Count;
int y = 0,rowsaffected;
cs.Open();
using (cs)
{
sqltxn = cs.BeginTransaction();
foreach (MyTable myBizObj in myBizObjList)
{
SqlCommand command = new SqlCommand(commandText, cs, sqltxn);
command.Parameters.Add("@empno", SqlDbType.Int);
command.Parameters["@empno"].Value = myBizObj.Empno;
command.Parameters.Add("@mydate", SqlDbType.Date);
command.Parameters["@mydate"].Value = myBizObj.Mydate;
command.Parameters.Add("@amt", SqlDbType.Decimal);
command.Parameters["@amt"].Value = myBizObj.Amt;
try
{
rowsAffected = command.ExecuteNonQuery();
if (rowsAffected == 1)
y++;
}
catch (Exception ex)
{
throw (ex);
}
}
if (y == x)
{
sqltxn.Commit();
}
else
{
sqltxn.Rollback();
y = 0;
}
cs.Close();
return y;
}
}
问题:我正在查询一个表并获得 50K 条记录,这些记录我正在转换为一个对象列表。我正在处理我的 BLL 中的列表并发送到我的 DAL。以上是我的 DAL 中的一个方法。有没有更好的办法?我还在检查是否所有行都已更新,然后是 Commit 或 Rollback。
【问题讨论】:
-
您可以使用
user defined table type和stored procedure在数据库端的单个事务中一次更新所有记录,而不是逐条更新50K 记录。 -
你需要用
using处理事务,你也应该把using(cs)移动到设置器cs = ...。你也可以缩短command.Parameters.Add("@empno", SqlDbType.Int).Value = myBizObj.Empno -
永远不要使用
throw ex;,其中ex是捕获的异常。您将丢失堆栈跟踪。只需执行throw;。当然......你的 catch 块除了重新抛出之外什么都不做,所以它完全是多余的,应该从这段代码中删除 try/catch。也不需要cs.Close();,using 块将确保连接在超出范围时关闭并释放。 -
@Charlieface 感谢 command.Parameters.Add("@empno", SqlDbType.Int).Value = myBizObj.Empno。少了一行代码。有很多东西要学。
标签: c#