如何在ASP.NET MVC Web API单POST请求中更新含外键关联的两张表
解决EF中关联表的批量插入问题
嘿,我来帮你搞定这个问题!核心原因很明确:你现在的代码先插入tblCountryName,但此时tblEmployeeRecord还没被保存到数据库,它的EmployeeId(自增主键)还没生成,导致tblCountryName的外键EmployeeId为空,直接触发了SQL Server的外键约束校验失败。
下面给你两种可行的解决方案,以及请求对象的说明:
方案一:调整保存顺序,手动赋值外键
这种方式不需要修改实体模型,只需要调整控制器里的保存逻辑:
[ResponseType(typeof(UserAndCountry))] public IHttpActionResult PosttblEmployeeRecord(UserAndCountry model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // 1. 先保存员工记录,此时EF会自动把SQL生成的自增EmployeeId赋值给model.UserRecord.EmployeeId db.tblEmployeeRecords.Add(model.UserRecord); db.SaveChanges(); // 2. 把生成的EmployeeId赋值给国家记录的外键 model.CountryRecord.EmployeeId = model.UserRecord.EmployeeId; db.tblCountryNames.Add(model.CountryRecord); db.SaveChanges(); return CreatedAtRoute("DefaultApi", new { id = model.UserRecord.EmployeeId }, model); }
方案二:利用EF导航属性自动管理关联(推荐)
这种方式需要给实体添加导航属性,让EF自动处理外键关联,代码更简洁:
第一步:修改实体模型,添加导航属性
// 员工表模型 public partial class tblEmployeeRecord { public int EmployeeId { get; set; } public string Name { get; set; } public string userName { get; set; } public string userRole { get; set; } // 添加导航属性(假设一个员工对应一条国家记录,一对一关系) public virtual tblCountryName Country { get; set; } } // 国家表模型 public partial class tblCountryName { public int CountryId { get; set; } public int EmployeeId { get; set; } public string Country_Name { get; set; } // 添加导航属性,关联到员工表 public virtual tblEmployeeRecord Employee { get; set; } }
第二步:修改控制器的保存逻辑
[ResponseType(typeof(UserAndCountry))] public IHttpActionResult PosttblEmployeeRecord(UserAndCountry model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // 关联两个实体,EF会自动处理外键赋值 model.UserRecord.Country = model.CountryRecord; // 只需要添加员工实体,EF会自动把关联的国家实体也插入数据库 db.tblEmployeeRecords.Add(model.UserRecord); db.SaveChanges(); return CreatedAtRoute("DefaultApi", new { id = model.UserRecord.EmployeeId }, model); }
请求对象说明
你当前的请求对象格式是完全没问题的,不需要修改:
{ "CountryRecord": { "Country_Name": "AP" }, "UserRecord": { "Name": "Test User", "userName": "Test.User@mail.com", "userRole": "Hr" } }
注意:不需要手动传EmployeeId,因为它是自增主键,EF会自动生成并赋值。
额外注意事项
- 确保
tblEmployeeRecord的EmployeeId在SQL Server中设置为自增IDENTITY,否则EF无法自动获取生成的主键值。 - 如果是一对多关系(一个员工对应多条国家记录),只需要把员工表的导航属性改成
public virtual ICollection<tblCountryName> Countries { get; set; },然后在控制器里把多个国家记录添加到这个集合即可。
内容的提问来源于stack exchange,提问作者Amardeep Gupta
相关产品推荐
相关产品推荐

