非MVC Razor页面中外键引用问题:添加Officer关联Agency报错
解决方案
步骤1:修改Officer模型,显式声明外键字段
EF Core会自动为导航属性生成外键(比如数据库里的AgencyId),但你需要在模型里显式添加这个字段,才能让视图正确绑定。修改后的代码如下:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace DWITracker.Model { public class Officer { [Key] public int Id { get; set; } [Display(Name ="Officer Name (Last, First, MI)")] public string? OfficerDisplayName { get; set; } [Display(Name = "First Name")] public string? OfficerFirstName { get; set; } [Display(Name = "MI")] public string? OfficerMiddleInitial { get; set; } [Display(Name = "Last Name")] public string? OfficerLastName { get; set; } // 显式添加外键字段,和数据库中的AgencyId列对应 [Display(Name = "Agency")] public int AgencyId { get; set; } // 用ForeignKey特性指定导航属性关联的外键 [ForeignKey(nameof(AgencyId))] public Agency Agency { get; set; } } }
说明:
- 添加
AgencyId字段后,和数据库里的列完全匹配,视图可以直接绑定这个字段 [ForeignKey]告诉EF Core,Agency导航属性对应的外键是AgencyId,确保关联关系正确
步骤2:修改视图的下拉框绑定
把视图里的绑定目标从Officer.Agency改成Officer.AgencyId,这样提交的是选中的Agency的ID值,而不是整个对象:
<td style="width: 40%"> <div class="mb-3"> <label asp-for="Officer.AgencyId"></label> <select asp-for="Officer.AgencyId" id="Select3" class="form-select" asp-items="@(new SelectList(Model.DisplayAgencyData.OrderBy(x => x.AgencyName),"Id", "AgencyName"))"> <option value="" selected disabled>---Select Associated Agency---</option> </select> </div> </td>
说明:
asp-for="Officer.AgencyId"会让下拉框选中的ID直接赋值给Officer的外键字段,符合表单提交的逻辑- 下拉框的选项数据源保持不变,依然用Agency的
Id作为值,AgencyName作为显示文本
步骤3:优化后台OnGet方法(可选)
原来的代码里有一行多余的查询,可以删掉,简化成:
public IEnumerable<Agency> DisplayAgencyData { get; set; } public async Task OnGet() { // 直接查询并排序Agency数据,不用在视图里重复排序 DisplayAgencyData = await _db.Agency.OrderBy(x => x.AgencyName).ToListAsync(); }
报错原因说明
之前的问题出在:模型里只有Agency导航属性,没有显式外键字段,EF自动生成了AgencyId列,但视图绑定的是整个Agency对象。提交表单时,无法把选中的ID转换成完整的Agency对象,导致模型验证失败,出现"The Agency field is required"的错误。显式添加外键字段后,绑定到AgencyId就能正确接收提交的ID值,解决验证问题。
内容的提问来源于stack exchange,提问作者MelB
相关产品推荐
相关产品推荐

