C#中ListView批量插入产品到SQL数据库仅最后一条生效是什么问题?
问题根因
- 产品插入执行时机错误:
cmd2.ExecuteNonQuery()放在foreach循环外部,循环过程中仅反复覆盖参数值,直到最后一次循环赋值完成后才执行1次插入,自然只有最后一条产品入库。 - 删除
cmd2.Parameters.Clear()后插入失败的原因:循环过程中会重复向cmd2.Parameters集合添加同名参数,参数名重复导致命令验证失败,无法执行。 - 参数绑定错误:
Cantitate、Dimensiuni、Comentarii三个字段全部绑定了item.SubItems[1],字段值会全部错误。 - 订单关联逻辑错误:目前仅获取最后一个产品的ID生成订单,其余插入的产品没有对应订单关联记录。
修复代码
如果你的业务是一个订单对应多个产品,建议先调整表结构,新增订单-产品关联表存储多对多关系,避免重复生成订单,修复后逻辑如下:
private void InsertOrder_Click(object sender, EventArgs e) { //---------------插入客户-------------------- SqlCommand cmd = new SqlCommand("InsertClients", con); cmd.CommandType = CommandType.StoredProcedure; if (TextBoxClientNou.Enabled) { cmd.Parameters.AddWithValue("@NumeClient", TextBoxClientNou.Text); } else { cmd.Parameters.AddWithValue("@NumeClient", ClientExistent.Text); } var IDClientParameter = cmd.Parameters.Add("@IDClient", SqlDbType.Int); IDClientParameter.Direction = ParameterDirection.Output; con.Open(); cmd.ExecuteNonQuery(); var IDClient = (int)IDClientParameter.Value; con.Close(); //---------------先插入订单主表-------------------- SqlCommand cmd3 = new SqlCommand("InsertOrders", con); cmd3.CommandType = CommandType.StoredProcedure; cmd3.Parameters.AddWithValue("@IDClient", IDClient); cmd3.Parameters.AddWithValue("@DataInceput", dateTimePicker1.Text); cmd3.Parameters.AddWithValue("@DataSfarsit", dateTimePicker2.Text); cmd3.Parameters.AddWithValue("@Facturata", factstatus); cmd3.Parameters.AddWithValue("@Livrata", livstatus); // 给存储过程加输出参数返回订单ID var IDOrderParameter = cmd3.Parameters.Add("@IDOrder", SqlDbType.Int); IDOrderParameter.Direction = ParameterDirection.Output; con.Open(); cmd3.ExecuteNonQuery(); var IDOrder = (int)IDOrderParameter.Value; con.Close(); //---------------循环插入所有产品-------------------- SqlCommand cmd2 = new SqlCommand("InsertProducts", con); cmd2.CommandType = CommandType.StoredProcedure; var IDProductParameter = cmd2.Parameters.Add("@IDProdus", SqlDbType.Int); IDProductParameter.Direction = ParameterDirection.Output; foreach (ListViewItem item in ListaProduse.Items) { cmd2.Parameters.Clear(); // 按你ListView实际列顺序调整下标 cmd2.Parameters.AddWithValue("@Denumire", item.Text); cmd2.Parameters.AddWithValue("@Cantitate", item.SubItems[1].Text); cmd2.Parameters.AddWithValue("@Dimensiuni", item.SubItems[2].Text); cmd2.Parameters.AddWithValue("@Comentarii", item.SubItems[3].Text); cmd2.Parameters.Add(IDProductParameter); con.Open(); cmd2.ExecuteNonQuery(); var IDProdus = (int)IDProductParameter.Value; con.Close(); // 插入订单-产品关联记录(需要提前新建关联表和对应存储过程) SqlCommand cmdMap = new SqlCommand("InsertOrderProductMap", con); cmdMap.CommandType = CommandType.StoredProcedure; cmdMap.Parameters.AddWithValue("@IDOrder", IDOrder); cmdMap.Parameters.AddWithValue("@IDProdus", IDProdus); con.Open(); cmdMap.ExecuteNonQuery(); con.Close(); } }
如果你的业务是每个产品对应一条独立订单,直接把原有插入订单的逻辑整体放到foreach循环内部即可。
优化建议
- 数据库连接请用
using块包裹,自动释放资源,避免连接泄漏 - 替换
AddWithValue为显式指定SqlDbType的Add方法,避免隐式类型转换导致的入库错误 - 所有数据库操作建议加
try-catch块捕获异常,方便排查问题
内容的提问来源于stack exchange,提问作者Chriss_1982
相关产品推荐
相关产品推荐

