当用户发送GET请求来编辑记录时,我正在加载使用.Include()发送到相关实体的视图的模型,如下所示:
var client = await _context.Client
.Include(c => c.Office)
.Where(c => c.client_id == id)
.AsNoTracking()
.SingleOrDefaultAsync();
return View(client);
当用户POST回编辑表单并且缺少必需字段ModelState.IsValid == false
时,不会执行任何更新,并且将未保存更改的模型发送回视图。
public async Task<IActionResult> Edit(Client client_edited )
{
if (!ModelState.IsValid)
{
return View(client_edited); // .Include(c => c.Office) is missing
}
}
如何返回发布的视图模型(包含用户待定更改)并重新附加所需的.Include()?
当我重新查询模型(客户端)记录时,挂起的更改将丢失。
我正在尝试做一些事情,比如重新查询包含的客户端,然后通过顶部的待定更改复制客户端。有点像...
var client = await _context.Client
.Include(c => c.Office)
.Where(c => c.client_id == id)
.AsNoTracking()
.SingleOrDefaultAsync();
// need to copy pending client_edited changes to the client
// but does not work because it overwrites the .Include(c => c.Office)
client = client_edited
return View(client_edited);
答案 0 :(得分:0)
回答我自己的问题以防其他人......
基于blog post by Lori Peterson Entity Framework cloning,参见 EF复制当前值 ,我能够通过几行代码解决问题,例如:
public async Task<IActionResult> Edit(Client client_posted)
{
if (!ModelState.IsValid)
{
ModelState.AddModelError("", "Record is missing required values");
// requery the client entity from our db to get related child entities
var client_current = await _context.Client
.Include(c => c.Office)
// include 4 or 5 more entities here
.Where(c => c.client_id == client_posted.client_id)
.AsNoTracking()
.SingleOrDefaultAsync();
// now replace client_current values with client_posted values by
// 1 - add entity to your db context (we are not saving it)
_myDbContext.Client.Add(client_posted);
// 2 - use the db context to extract current values from the client entity posted
var client_posted_values =_myDbContext.Entry(client_posted).CurrentValues;
// 3 - copy the extracted values to the client_current we re-queried from db
_myDbContext.Entry(client_current).CurrentValues.SetValues(client_posted_values);
// 4 return the view passing client with original values and the attached office entity(ies)
return View(client_current);
}
// otherwise ModelState is valid, do the update here
...
...
}