如何在视图中展示1对1关联数据并提交时更新对应数据表
问题解决方案
1. 修复EnvelopeNumber显示空白的问题
问题根源是FindAsync方法不会自动加载EF Core的导航属性,导致member.Envelope为null,视图无法读取EnvelopeNumber。只需修改GET Edit方法,显式加载关联的Envelope:
修改MembersController的GET Edit方法
// GET: Members/Edit/5 public async Task<IActionResult> Edit(int? id) { if (id == null) { return NotFound(); } // 显式加载关联的Envelope导航属性 var member = await _context.Member .Include(m => m.Envelope) .FirstOrDefaultAsync(m => m.MemberId == id); if (member == null) { return NotFound(); } return View(member); }
可选:完善1对1关联配置(推荐)
当前模型缺少Envelope到Member的反向导航,建议补充以确保关联关系正确:
public class Envelope { [Key] public int EnvelopeId { get; set; } [Required] [Display(Name = "Envelope Number")] public int EnvelopeNumber { get; set; } // 添加反向导航与外键 [ForeignKey("Member")] public int MemberId { get; set; } public virtual Member? Member { get; set; } }
2. 实现Member与Envelope独立提交更新
通过区分提交按钮的标识,让后端知道要更新哪个实体,或者拆分独立的提交Action,这里提供两种方案:
方案一:同一Action区分提交类型
步骤1:修改视图的提交按钮与表单
给两个提交按钮添加name属性,并在Envelope表单中加入EnvelopeId隐藏字段:
<!-- Member表单的提交按钮 --> <input type="submit" name="submitAction" value="SaveMember" class="btn btn-primary" /> <!-- Envelope表单内容 --> <form asp-action="Edit"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <input type="hidden" asp-for="MemberId" /> @if (Model.Envelope != null) { <input type="hidden" asp-for="Envelope.EnvelopeId" /> } <!-- 其余Envelope字段代码不变 --> <input type="submit" name="submitAction" value="SaveEnvelope" class="btn btn-primary" /> </form>
步骤2:添加POST Edit方法处理不同提交
// POST: Members/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, string submitAction, Member member, Envelope envelope) { if (id != member.MemberId) { return NotFound(); } if (ModelState.IsValid) { try { if (submitAction == "SaveMember") { _context.Update(member); } else if (submitAction == "SaveEnvelope") { envelope.MemberId = id; if (envelope.EnvelopeId == 0) { _context.Add(envelope); } else { _context.Update(envelope); } } await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!MemberExists(member.MemberId)) { return NotFound(); } throw; } return RedirectToAction(nameof(Index)); } // 验证失败时重新加载Envelope返回视图 member.Envelope = await _context.Envelope.FindAsync(envelope.EnvelopeId); return View(member); } private bool MemberExists(int id) { return _context.Member.Any(e => e.MemberId == id); }
方案二:拆分独立提交Action(更清晰)
步骤1:修改视图表单的asp-action
<!-- Member表单 --> <form asp-action="SaveMember"> <!-- 内容不变 --> </form> <!-- Envelope表单 --> <form asp-action="SaveEnvelope"> <input type="hidden" asp-for="MemberId" /> @if (Model.Envelope != null) { <input type="hidden" asp-for="Envelope.EnvelopeId" /> } <!-- 其余Envelope字段代码不变 --> </form>
步骤2:添加对应的提交Action
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> SaveMember(Member member) { if (ModelState.IsValid) { try { _context.Update(member); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!MemberExists(member.MemberId)) return NotFound(); throw; } return RedirectToAction(nameof(Index)); } member.Envelope = await _context.Envelope.FindAsync(member.MemberId); return View("Edit", member); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> SaveEnvelope(int memberId, Envelope envelope) { if (ModelState.IsValid) { try { envelope.MemberId = memberId; if (envelope.EnvelopeId == 0) { _context.Add(envelope); } else { _context.Update(envelope); } await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!EnvelopeExists(envelope.EnvelopeId)) return NotFound(); throw; } return RedirectToAction(nameof(Index)); } var member = await _context.Member.Include(m => m.Envelope).FirstOrDefaultAsync(m => m.MemberId == memberId); return View("Edit", member); } private bool EnvelopeExists(int id) { return _context.Envelope.Any(e => e.EnvelopeId == id); }
内容的提问来源于stack exchange,提问作者Bob H
相关产品推荐
相关产品推荐

