ASP.NET MVC按条件批量插入单模型多条记录报错求解
问题背景
目标是实现账单批量生成:管理员在表单仅填写月份、年份字段后,系统自动为所有满足TRANGTHAI == 1(在用状态)的房间生成对应账单,替代手动逐间录入的繁琐操作。
原有代码错误排查
第一版代码存在的问题
- 类型使用错误:将房间查询结果定义为
dynamic类型,且LINQ逻辑select p.ID_PHONG返回的是List<int>(集合内每个元素都是整数类型的房间ID),遍历集合时调用phong.ID_PHONG相当于给int类型取不存在的属性,直接抛出'int' does not contain a definition for 'ID_PHONG'异常。 - 逻辑位置错误:
return RedirectToAction("Index")写在foreach循环内部,第一次循环执行完就直接触发跳转,既不会处理后续房间的账单生成,也不会执行db.SaveChanges()提交数据到数据库。 - 语法错误:实体属性赋值时
TRANGTHAI = "Chua dong tien"行末尾缺少逗号,代码无法正常编译。 - 参数遗漏:没有读取视图传入的月份、年份输入值,无法按管理员填写的时间生成账单。
- 健壮性不足:直接读取
Session["ID"]没有做空值校验,Session过期时会抛出空引用异常。
第二版代码存在的问题
- 数据源错误:将单个int类型的
vm.Phong.ID_PHONG作为LINQ查询的数据源,对整数类型调用Where方法,直接抛出Could not find an implementation of the query pattern for source type 'int'. 'Where' not found.异常。 - 硬编码问题:月份字段写死为
1,没有读取用户在表单输入的月份值。
修复后实现代码
首先确认视图模型包含表单需要接收的两个字段:
public class ViewModel_HoaDon { [Required(ErrorMessage = "请选择账单月份")] [Range(1,12,ErrorMessage = "月份范围为1-12")] public int THANG { get; set; } [Required(ErrorMessage = "请选择账单年份")] [Range(2000,2100,ErrorMessage = "请输入有效年份")] public int NAM { get; set; } }
控制器Post方法修正如下:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(ViewModel_HoaDon vm) { if (!ModelState.IsValid) { return View(vm); } // 校验登录状态 if (Session["ID"] == null) { return RedirectToAction("Login", "Account"); } int createUserId = int.Parse(Session["ID"].ToString()); // 查询所有在用房间的ID集合,明确指定类型不要用dynamic List<int> activeRoomIds = db.PHONGs .Where(p => p.TRANGTHAI == 1) .Select(p => p.ID_PHONG) .ToList(); // 遍历生成账单 foreach (int roomId in activeRoomIds) { // 每次循环必须new一个新的账单实体,避免重复引用同一个对象 HOADON newBill = new HOADON { ID_PHONG = roomId, ID_DONGIA = 1, TRANGTHAI = "Chua dong tien", THANG = vm.THANG, NAM = vm.NAM, ID_CANBO = createUserId }; db.HOADONs.Add(newBill); } // 所有账单添加完成后统一提交,批量操作单次提交性能远高于循环内多次提交 db.SaveChanges(); return RedirectToAction("Index"); }
可选优化建议
- 增加重复账单校验:生成账单前先判断对应房间、对应年月是否已经存在账单,避免重复生成。
- 数据量较大时(比如房间数超过100间),可以使用EF批量插入类库减少数据库交互次数,提升插入效率。
- 视图端要加 antiforgery 令牌,避免跨站请求伪造攻击。
内容的提问来源于stack exchange,提问作者ChilliCandy
相关产品推荐
相关产品推荐

