You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    });
}

额外优化点

  1. 移除CreateGET方法中手动设置的TeamMemberId = 1,因为新增的成员还未保存到数据库,ID应该由EF Core自动生成(如果你的TeamMemberId是自增主键的话):
public IActionResult Create()
{
    Team team = new Team();
    team.TeamMembers.Add(new TeamMember()); // 去掉手动设置的TeamMemberId
    return PartialView("_AddTeamPartialView", team);
}
  1. 确保你的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:31:03