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

ASP.NET Core主从表更新时添加空行重复最后一行数据问题

问题排查与解决

核心问题根源

添加空行时直接克隆已有行的DOM元素,未清空字段值,且未生成新的唯一索引,导致ASP.NET Core模型绑定将新行识别为重复项,最终出现重复最后一行数据的情况。

分步解决方案

1. 修正视图的集合项渲染逻辑

在Update.cshtml中使用for循环遍历从数据集合,确保每个项的索引唯一且连续:

@model YourNamespace.EntrepotViewModel

<form asp-action="Update" method="post">
    <!-- 主数据字段 -->
    <input asp-for="Entrepot.Id" type="hidden" />
    <div class="form-group">
        <label asp-for="Entrepot.Name"></label>
        <input asp-for="Entrepot.Name" class="form-control" />
    </div>

    <!-- 从数据表格 -->
    <table id="emplacementTable" class="table">
        <thead>
            <tr>
                <th>位置名称</th>
                <th>描述</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            @for (int i = 0; i < Model.Emplacements.Count; i++)
            {
                <tr>
                    <td><input asp-for="Emplacements[i].Name" class="form-control" /></td>
                    <td><input asp-for="Emplacements[i].Description" class="form-control" /></td>
                    <td><button type="button" class="btn btn-danger" onclick="removeRow(this)">删除</button></td>
                    <input asp-for="Emplacements[i].Id" type="hidden" />
                </tr>
            }
        </tbody>
    </table>
    <button type="button" id="addRowBtn" class="btn btn-primary">添加空行</button>
    <button type="submit" class="btn btn-success">保存</button>
</form>

2. 重写JS添加行逻辑,生成全新空行

替换原添加行的脚本,手动构建空行DOM,避免克隆旧数据,并生成新索引:

document.getElementById('addRowBtn').addEventListener('click', function() {
    const tableBody = document.getElementById('emplacementTable').querySelector('tbody');
    const rowCount = tableBody.children.length;

    const newRow = document.createElement('tr');
    newRow.innerHTML = `
        <td><input name="Emplacements[${rowCount}].Name" class="form-control" /></td>
        <td><input name="Emplacements[${rowCount}].Description" class="form-control" /></td>
        <td><button type="button" class="btn btn-danger" onclick="removeRow(this)">删除</button></td>
        <input name="Emplacements[${rowCount}].Id" type="hidden" value="" />
    `;

    tableBody.appendChild(newRow);
});

function removeRow(btn) {
    btn.closest('tr').remove();
    // 删除后重新整理索引,保证模型绑定正常
    const rows = document.getElementById('emplacementTable').querySelector('tbody').children;
    Array.from(rows).forEach((row, index) => {
        const inputs = row.querySelectorAll('input');
        inputs.forEach(input => {
            input.name = input.name.replace(/Emplacements\[\d+\]/, `Emplacements[${index}]`);
        });
    });
}

3. 控制器端完善模型绑定与数据处理

确保Update方法能正确处理动态集合的新增、更新与删除:

[HttpPost]
public IActionResult Update(EntrepotViewModel viewModel)
{
    if (!ModelState.IsValid) return View(viewModel);

    // 更新主数据
    _context.Entrepots.Update(viewModel.Entrepot);

    // 处理从数据:删除已移除的项
    var existingEmplacements = _context.Emplacements.Where(e => e.EntrepotId == viewModel.Entrepot.Id).ToList();
    foreach (var existing in existingEmplacements)
    {
        if (!viewModel.Emplacements.Any(e => e.Id == existing.Id))
        {
            _context.Emplacements.Remove(existing);
        }
    }

    // 新增或更新从数据项
    foreach (var emplacement in viewModel.Emplacements)
    {
        emplacement.EntrepotId = viewModel.Entrepot.Id;
        if (emplacement.Id == 0)
        {
            _context.Emplacements.Add(emplacement);
        }
        else
        {
            _context.Emplacements.Update(emplacement);
        }
    }

    _context.SaveChanges();
    return RedirectToAction("Index");
}

4. 视图模型定义参考

确保视图模型包含正确的主从数据结构:

public class EntrepotViewModel
{
    public Entrepot Entrepot { get; set; }
    public List<Emplacement> Emplacements { get; set; } = new List<Emplacement>();
}

关键注意点

  • 必须用for循环渲染集合项,ASP.NET Core模型绑定依赖连续且唯一的索引识别集合元素。
  • 添加新行时避免克隆已有行,手动构建空字段防止旧数据残留。
  • 删除行后重新整理索引,避免索引断层导致模型绑定失败。

内容的提问来源于stack exchange,提问作者Issouf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:05:21