在.NET 8 Razor Page中解决多对多关联保存重复数据问题
解决Product与Color多对多关系中Quantity属性的正确绑定问题
问题根源
- 视图中
ColorQuantities输入框未与对应ColorId关联,提交时无法区分数量所属的颜色 - 服务层嵌套循环导致每个选中颜色遍历所有数量,产生重复插入数据
修复步骤
1. 修改视图代码,关联颜色与数量输入框
将数量输入框的名称改为带ColorId的格式,同时通过JS控制输入框的启用状态,避免无效数据提交:
<div class="form-group"> <label>Colors</label> @{ var colors = ViewData["Colors"] as List<Color>; } @foreach (Color color in colors) { <div> <input type="checkbox" name="SelectedColors" value="@color.ColorId" id="color_@color.ColorId"/> <label for="color_@color.ColorId">@color.ColorName</label> <div> <label>تعداد</label> <!-- 用ColorId作为键绑定对应数量,默认禁用输入框 --> <input type="number" name="ColorQuantities[@color.ColorId]" class="form-control" disabled="true" min="1"/> </div> <hr/> </div> } </div> <script> // 复选框选中/取消时控制数量输入框状态 document.querySelectorAll('input[name="SelectedColors"]').forEach(checkbox => { checkbox.addEventListener('change', function() { const quantityInput = document.querySelector(`input[name="ColorQuantities[${this.value}]"]`); quantityInput.disabled = !this.checked; if (!this.checked) quantityInput.value = ''; }); }); </script>
2. 调整后台Post方法,接收关联的颜色与数量
将List<int>? ColorQuantities替换为Dictionary<int, int> ColorQuantities,直接获取ColorId与Quantity的对应关系:
public IActionResult OnPost(IFormFile imgProductUp, List<int> SelectedColors, Dictionary<int, int> ColorQuantities) { if (!ModelState.IsValid) { ViewData["Colors"] = _colorService.GetAllColors(); return Page(); } int productId = _productService.AddProduct(Product, imgProductUp); _productService.AddColorToProductByAdmin(productId, SelectedColors, ColorQuantities); return RedirectToPage("Index"); }
3. 修改服务层代码,正确插入ProductColor数据
去掉嵌套循环,遍历选中的颜色并从字典中匹配对应数量:
public void AddColorToProductByAdmin(int productId, List<int> SelectedColors, Dictionary<int, int> ColorQuantities) { foreach (int colorId in SelectedColors) { // 尝试获取对应颜色的数量,无值时可设置默认值(如0) if (ColorQuantities.TryGetValue(colorId, out int quantity)) { _context.ProductColors.Add(new ProductColor() { ProductId = productId, ColorId = colorId, Quantity = quantity }); } } _context.SaveChanges(); }
额外说明
- 可在后台添加验证逻辑,比如检查选中颜色对应的Quantity是否大于0,避免非法数据入库
- 前端JS仅为提升用户体验,即使不添加,后台通过字典绑定也能正确关联颜色与数量
内容的提问来源于stack exchange,提问作者Ghasem Shahrokhi
相关产品推荐
相关产品推荐

