如何用Entity Framework更新数据库?DataGridView库存增量更新问题求助
排查DataGridView更新数据库失败的问题
我来帮你梳理这段代码里的问题,你想要实现的是匹配DataGridView中的产品名后,增量更新库存并同步到数据库,现在没成功,主要是这几个关键问题:
1. EF实体状态设置语法错误
你代码里的context.Entry.state = Entrystate.modified;是完全错误的写法:
- 首先
Entry()方法需要传入你要修改的实体对象obj5; - 其次状态枚举的正确写法是
EntityState.Modified(注意大小写,且需要引用System.Data.Entity命名空间)。
正确的写法应该是:
context.Entry(obj5).State = EntityState.Modified;
2. 重复赋值导致的冗余(虽不影响功能,但需要优化)
你代码里连续两次给obj5.Quantity赋值:
obj5.Quantity = Convert.ToInt32(row.Cells[5].Value); // ... obj5.Quantity = Convert.ToInt32(row.Cells[5].Value);
这完全没必要,保留一次即可。
3. 实体跟踪的潜在问题
如果obj5是你新创建的对象,而不是从当前context中查询出来的实体,直接设置Modified状态可能会让EF无法正确识别要更新的数据库记录。这种情况下,你可以先查询数据库中对应的实体,再修改它的属性:
// 先从数据库查询对应产品的实体 var existingProduct = context.Products.FirstOrDefault(p => p.ProductName == bunifuTextBox11.Text); if (existingProduct != null) { // 增量更新库存 existingProduct.Quantity += Convert.ToInt32(bunifuTextBox10.Text); existingProduct.CostPricePerProduct = Convert.ToInt32(row.Cells[3].Value); existingProduct.SellingPricePerProduct = Convert.ToInt32(row.Cells[4].Value); existingProduct.ExpiryDate = Convert.ToString(row.Cells[6].Value); existingProduct.ProductNumber = obj2.ProductNumber; // 因为是从context查询出来的,EF会自动跟踪修改,不需要手动设置Modified context.SaveChanges(); }
4. 未处理DBNull的风险
DataGridView的单元格值可能是DBNull.Value,直接用Convert.ToInt32会抛出异常,建议先做空值检查:
// 示例:检查库存数量单元格是否为空 if (row.Cells[5].Value != DBNull.Value) { var currentQuantity = Convert.ToInt32(row.Cells[5].Value); obj5.Quantity = currentQuantity + Convert.ToInt32(bunifuTextBox10.Text); }
修正后的完整代码示例
if (bunifuDataGridView1.Rows.Count > 0) { bool found = false; foreach (DataGridViewRow row in bunifuDataGridView1.Rows) { // 跳过新行(如果DataGridView允许添加新行的话) if (row.IsNewRow) continue; var productName = Convert.ToString(row.Cells[2].Value); if (productName == bunifuTextBox11.Text) { // 处理空值,避免转换异常 if (row.Cells[5].Value == DBNull.Value || string.IsNullOrEmpty(bunifuTextBox10.Text)) { // 可以在这里加提示,比如MessageBox.Show("库存数量或输入值无效"); continue; } // 计算新的库存数量 var newQuantity = Convert.ToInt32(row.Cells[5].Value) + Convert.ToInt32(bunifuTextBox10.Text); // 更新DataGridView显示 row.Cells[5].Value = newQuantity.ToString(); // 方法二:如果obj5是新实例,需要Attach并设置状态 obj5.ProductName = productName; obj5.CostPricePerProduct = Convert.ToInt32(row.Cells[3].Value); obj5.SellingPricePerProduct = Convert.ToInt32(row.Cells[4].Value); obj5.Quantity = newQuantity; obj5.ExpiryDate = Convert.ToString(row.Cells[6].Value); obj5.ProductNumber = obj2.ProductNumber; // 先Attach到上下文(如果之前没跟踪) var entry = context.Entry(obj5); if (entry.State == EntityState.Detached) { context.Products.Attach(obj5); } entry.State = EntityState.Modified; context.SaveChanges(); inboundgoods(); refreshcustomergrid(); found = true; // 找到匹配项后跳出循环,避免重复处理(产品名应该唯一) break; } } if (!found) { inboundgoods(); } } else { inboundgoods(); }
另外还有个小优化:找到匹配的产品行后,用break跳出循环,因为产品名应该是唯一的,没必要继续遍历剩下的行。
内容的提问来源于stack exchange,提问作者teyim
相关产品推荐
相关产品推荐

