.NET 5.0 Razor Pages如何批量插入多条数据到SQL Server?
问题分析与解决方案
问题根源是前端表单未生成符合集合模型绑定的字段格式,导致后端只能接收到单个对象,而非多个服务的集合。以下是具体修正步骤:
1. 修正页面Model定义
页面Model中需将单个ClientService对象替换为集合类型,确保能接收多条数据:
public class YourPageModel : PageModel { public int CliIdOk { get; set; } // 改为List集合并初始化 public List<ClientService> ClientServices { get; set; } = new List<ClientService>(); // 其他依赖注入、属性定义... }
2. 初始化集合(OnGet方法)
在页面的OnGet方法中,提前初始化对应数量的集合元素(18到39共22个服务):
public void OnGet(int cliId) { CliIdOk = cliId; // 传入当前客户ID // 生成22个空的ClientService对象,供前端绑定使用 ClientServices = Enumerable.Range(18, 22) .Select(_ => new ClientService()) .ToList(); }
3. 修正前端表单循环代码
将原循环改为按集合索引绑定,确保每个输入字段的name属性为ClientServices[index].XXX格式,ASP.NET Core才能正确识别为集合:
<form method="post"> <div class="col-md-12"> @for (int i = 0; i < Model.ClientServices.Count; i++) { var servId = 18 + i; <input asp-for="ClientServices[i].CliId" class="form-control" value="@Model.CliIdOk" hidden /> <input asp-for="ClientServices[i].ServId" value="@servId" hidden /> <div class="border-0" style="width: 6%; height: 150px; min-width: 30px; float: left; "> <div class="form-group form-check" style="position:relative;left:-15px;"> <label class="form-check-label btn btn-sm fw-bold border m-1 p-1" style="border-radius:16px;"> <input asp-for="ClientServices[i].Active" style="border-radius:16px;position:relative;" /> <br /> @servId </label> </div> </div> } </div> <button class="btn btn-sm btn-outline-primary fw-bold" type="submit" style="font-size: 120%;float:unset;min-width:120px;"> Save </button> </form>
4. 修正后端OnPost代码
过滤出用户选中的(Active=true)服务再批量保存,同时恢复ModelState验证排查绑定问题:
public async Task<IActionResult> OnPostAsync() { try { if (!ModelState.IsValid) { // 若模型绑定失败,返回页面查看具体错误 return Page(); } // 仅保存用户选中的服务 var selectedServices = ClientServices.Where(s => s.Active).ToList(); _context.ClientServices.AddRange(selectedServices); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); } catch (Exception e) { // 建议添加日志记录,方便后续排查错误 // _logger.LogError(e, "批量保存客户服务失败"); return RedirectToPage("./Index"); } }
关键说明
- 原前端代码中所有输入字段的
name属性均为ClientServices.CliId、ClientServices.ServId,提交时同名字段会互相覆盖,最终仅保留最后一条(或浏览器提交的第一条)数据。 - 通过集合索引绑定生成的
name属性为ClientServices[0].CliId、ClientServices[1].CliId...,ASP.NET Core会自动将这些值绑定到List<ClientService>集合中。
内容的提问来源于stack exchange,提问作者Fillo
相关产品推荐
相关产品推荐

