使用Web API,我想用PUT方法更新一条记录和两个m-to-n关系表。为此,我找到了Entity Framework的更新方法。但是,我的代码再往下就什么都不做了。是不是我从根本上误解了什么?
[HttpPut("Roles/{roleID}")]
public async Task<ActionResult> UpdateRole(int roleID, Role updatedRole) {
// Validate data
if (roleID != updatedRole.ID)
return BadRequest("ID missmatch.");
if (!updatedRole.Validate(out string problems))
return BadRequest(problems);
// Apply modified relations
updatedRole.ApplyModifiedRelations();
// Setup db connection
MpaContext db = _mpaContext;
Response.RegisterForDispose(db);
// Save changes
db.Update(updatedRole);
// I've added these two afterwords, but it also doesn't update anything
if (updatedRole.HasModifiedClientIDs)
db.UpdateRange(updatedRole.ClientRoles);
if(updatedRole.HasModifiedViewerIDs)
db.UpdateRange(updatedRole.RoleViewers);
try {
await db.SaveChangesAsync();
} catch (Exception ex) {
return Problem(ex.Message);
}
return Ok();
}
public void ApplyModifiedRelations() {
if (HasModifiedClientIDs) {
ClientRoles = new List<ClientRole>(
_ClientIDs.Select(c => new ClientRole() { ClientID = c, RoleID = ID })
);
}
if (HasModifiedViewerIDs) {
RoleViewers = new List<RoleViewer>(
_ViewerIDs.Select(v => new RoleViewer() { RoleID = ID, ViewerID = v })
);
}
}
我认为你的对象在db上下文中不存在(因为你是从request中获取的)。所以EF无法更新它。
db.Entry(updatedRole).State = EntityState.Modified;
db.SaveChanges();
我找到了解决方案。你必须在更新关系之前实际加载关系。我相应地修改了我的ApplyModifiedRelations方法。
public async Task ApplyModifiedRelations(MpaContext db) {
if (HasModifiedClientIDs) {
await db.Entry(this).Collection(r => r.ClientRoles).LoadAsync();
ClientRoles = new List<ClientRole>(
_ClientIDs.Select(c => new ClientRole() { ClientID = c, RoleID = ID })
);
}
if (HasModifiedViewerIDs) {
await db.Entry(this).Collection(r => r.RoleViewers).LoadAsync();
RoleViewers = new List<RoleViewer>(
_ViewerIDs.Select(v => new RoleViewer() { RoleID = ID, ViewerID = v })
);
}
}
我还把那个方法调用移到了 db.Update
呼叫。但我不知道,如果这有什么不同。