【问题标题】:Redisplay original Model with .Include( related-entity ) after update validation fails更新验证失败后重新显示带有 .Include(related-entity) 的原始模型
【发布时间】:2018-08-01 22:11:33
【问题描述】:

当用户发送 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);

【问题讨论】:

    标签: c# asp.net-core entity-framework-core


    【解决方案1】:

    回答我自己的问题,以防它帮助别人......

    基于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
      ...
      ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      • 2014-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多