ASP.NET Core主从模型新增时删除成员后数据丢失问题排查
问题根源分析
你遇到的问题核心是ASP.NET Core模型绑定对集合的索引要求必须连续且从0开始。当删除第一行后,剩余成员行的HTML输入框name属性里的索引是[1]、[2]这类非连续值,模型绑定只会识别从[0]开始的连续索引,所以后面的成员数据无法被正确绑定到Team.TeamMembers集合中。
解决方案
需要在删除成员行之后,重新遍历所有剩余行,将它们的索引从0开始重新编号,确保name属性的索引连续。同时修正hdnLastIndex的逻辑,避免索引混乱。
修改后的前端脚本代码
function DeleteItem(btn) { // 删除当前行 $(btn).closest('tr').remove(); // 重新编号所有剩余行的索引 reindexRows(); // 更新最后索引值 document.getElementById('hdnLastIndex').value = document.getElementById('membersTable').querySelectorAll('tbody tr').length - 1; } function AddItem(btn) { var table = document.getElementById('membersTable'); var rows = table.querySelectorAll('tbody tr'); var lastRow = rows[rows.length - 1]; var lastrowIdx = parseInt(document.getElementById('hdnLastIndex').value); var RowNumber = parseInt(document.getElementById('NumberOfTeamMembers').value); var nextrowIdx = lastrowIdx + 1; if (nextrowIdx < RowNumber) { // 克隆最后一行并修改索引 var newRow = lastRow.cloneNode(true); // 替换所有索引相关的属性 newRow.innerHTML = newRow.innerHTML.replaceAll('_' + lastrowIdx + '_', '_' + nextrowIdx + '_'); newRow.innerHTML = newRow.innerHTML.replaceAll('[' + lastrowIdx + ']', '[' + nextrowIdx + ']'); newRow.innerHTML = newRow.innerHTML.replaceAll('-' + lastrowIdx, '-' + nextrowIdx); // 添加新行 table.querySelector('tbody').appendChild(newRow); document.getElementById('hdnLastIndex').value = nextrowIdx; } } // 新增的索引重排函数 function reindexRows() { var rows = document.getElementById('membersTable').querySelectorAll('tbody tr'); rows.forEach(function(row, index) { // 替换行内所有元素的索引标识 row.innerHTML = row.innerHTML.replaceAll(/\[(\d+)\]/g, '[' + index + ']'); row.innerHTML = row.innerHTML.replaceAll(/_(\d+)_/g, '_' + index + '_'); row.innerHTML = row.innerHTML.replaceAll(/-(\d+)/g, '-' + index); }); }
额外优化点
- 移除
CreateGET方法中手动设置的TeamMemberId = 1,因为新增的成员还未保存到数据库,ID应该由EF Core自动生成(如果你的TeamMemberId是自增主键的话):
public IActionResult Create() { Team team = new Team(); team.TeamMembers.Add(new TeamMember()); // 去掉手动设置的TeamMemberId return PartialView("_AddTeamPartialView", team); }
- 确保你的
Team和TeamMember模型配置了正确的主外键关系,示例如下:
public class Team { public int TeamId { get; set; } public string TeamName { get; set; } public string Coach { get; set; } public int NumberTeamMembers { get; set; } public List<TeamMember> TeamMembers { get; set; } = new List<TeamMember>(); } public class TeamMember { public int TeamMemberId { get; set; } public string Name { get; set; } public DateTime BirthDate { get; set; } public string Phone { get; set; } public int TeamId { get; set; } // 外键 public Team Team { get; set; } // 导航属性 }
原理说明
ASP.NET Core的模型绑定器在绑定集合时,依赖于连续的整数索引(从0开始)来识别集合中的元素。如果索引不连续,绑定器会认为中间的元素不存在,只会绑定到第一个有效索引(0)的元素,后续的元素会被忽略。通过删除行后重新索引,可以确保所有剩余元素的索引都是连续的,从而被正确绑定到模型中。
内容的提问来源于stack exchange,提问作者user3309231
相关产品推荐
相关产品推荐

