TryUpdateModelAsync 发生了什么?

28
所以我正在学习这个关于ASP.NET Core和EF 6的微软教程,它刚刚通过编辑控制器更新了一个模型。

有一段代码让我感到很困惑,我想象(也许希望)这对许多人来说并不困惑。

var studentToUpdate = await _context.Students.SingleOrDefaultAsync(s => s.ID == id);

if (await TryUpdateModelAsync<Student>(
          studentToUpdate, 
          "", 
           s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate))
// goes on to save the context
因此,这个控制器只需要一个int id作为参数,这就是它如何掌握studentToUpdate的方式。我不完全熟悉的是,它从哪里获取更新值?
我所知道的:
- TryUpdateModelAsync<Student> - 第一个参数:要更新的模型 - 第二个参数:前缀(?),引用中的前缀:在.中查找值时使用的前缀 - 第三个参数:我认为与我正在寻找的解决方案有关的linq语句。
- 运行调试器,在函数执行之前studentToUpdate.FirstMidNamesCarson(原始),但在函数执行之后,它变成了Carsey(新的)。字符串Carsey始终在this>Request>Form>Results View中(其中包含表单中所有值的列表)。
因此,我理解TryUpdateModelAsync函数以某种方式使用linq语句和表单结果来获取studentToUpdate的新值,但我真的不知道它是如何做到的和在哪里完成的?

谢谢!我会仔细阅读的。 - MrJalapeno
@Nkosi 所以这个链接语句是在查询表单值吗?将它们绑定到 s 上,然后再用来更新 studentToUpdate? - MrJalapeno
换句话说,它使用Lambda表达式来确定路由值和模型中要查找的属性。然后将这些值更新到模型中。 - Nkosi
源代码:https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs#L1973 - Evan Mulawski
前缀参数在文档中有一些解释:https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0#complex-types - Steve Nyholm
显示剩余3条评论
2个回答

22

不需要过多涉及技术细节,提供的例子中调用TryUpdateModelAsync

if (await TryUpdateModelAsync<Student>(
      studentToUpdate, 
      "", 
       s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate)){
    //...
}

使用控制器当前的ControllerContext中提供的数据,更新指定的Student实例studentToUpdate。此过程使用表示顶级属性的lambda表达式,这些属性需要在尝试更新当前模型时包括在内。它将仅采用这些属性的值并更新模型。

因此,在上面的示例中,即使整个模型都由表单提供,它也只会更新指定实例上的FirstMidNameLastNameEnrollmentDate


1
我认为最令人困惑的是第三个参数:一个linq语句。
每个linQ表达式 [i => i.property] 将与表格内或约束(外键、索引等)中的每一列相匹配(在EF MVC中我们所知道的是导航属性)。
因此,第三个参数决定了应该异步更新到数据库中的内容。它通过模型绑定来完成链接到模型绑定

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接