【问题标题】:How do I update only the properties of my models that have changed in MVC?如何仅更新 MVC 中已更改的模型的属性?
【发布时间】:2010-10-27 01:37:37
【问题描述】:

我正在开发一个允许编辑记录的网络应用程序。有可能两个用户同时在同一个屏幕上工作,如果他们都点击保存,我想尽量减少造成的损害。

如果用户 1 请求该页面,然后更改地址、电话和联系方式,但在他单击保存之前,用户 2 请求相同的页面。

User1 然后点击保存并使用 TryUpdateModel() 更新整个模型,如果 User2 只是将一些细节附加到 Notes 字段,当他保存时,TryUpdateModel() 方法将用旧细节覆盖 User1 保存的新细节.

我考虑过将所有模型属性的原始值存储在隐藏的表单字段中,然后编写自定义 TryUpdateModel 以仅更新已更改的属性,但这感觉有点像我们都拥有的 Viewstate迁移到 MVC 后,我非常乐意离开。

有没有我不知道的处理这个问题的模式?

你会怎么处理?

更新:在回答下面的 cmets 时,我正在使用实体框架。

安东尼

【问题讨论】:

  • 这可以在 Repository/DataContext 级别处理。您使用的是什么数据库/数据访问方法?
  • 是的..如果您告诉我们您正在使用什么 ORM,我们可以提供帮助..(例如 Linq to SQL/Entities),因为大多数 ORM 都有处理并发问题的方法..这就是您已经解释过了。

标签: asp.net-mvc model-view-controller entity-framework


【解决方案1】:

除非您对在这种情况下发生的事情有任何特殊要求(例如锁定记录,这当然需要一些功能来在用户决定不进行更改时撤消锁定)我建议正常方法是乐观锁:

您执行的每次更新都应检查记录是否在此期间没有更改。

所以:

  1. 将整数“版本”属性或 guid / rowversion 记录在案。
  2. 确保它包含在 html 的隐藏字段中,因此在任何提交时都会返回;
  3. 当您执行更新时,确保(数据库)记录的版本/guid/rowversion 仍然与隐藏字段中的值匹配 [并且在执行更新时将 1 加到“版本”整数中,如果您已经决定采用这种手动方法。]

类似的方法显然是在记录上使用日期/时间戳,但不要这样做,因为在系统时钟的准确性范围内,它是有缺陷的。

[我建议您在其他地方找到对整个方法的更全面的解释。当然,如果您要通过 Google 搜索有关 NHibernate 版本功能的信息...]

【讨论】:

    【解决方案2】:

    在一个用户处理页面时锁定对页面的修改是一种选择。这是在一些 wiki 软件(如 dokuwiki)中完成的。在这种情况下,它通常会在 5-10 分钟不活动后使用一些 javascript 来释放锁,以便其他人可以更新它。

    另一种选择可能是将所有修订存储在数据库中,因此当两个用户提交时,两个副本都被保存并且仍然存在。从那里开始,您需要做的就是将两者合并。

    【讨论】:

      【解决方案3】:

      你通常不会处理这个。如果两个用户碰巧同时编辑一个文档并提交他们的更新,则其中一个获胜,另一个失败。

      资源锁定可以通过有状态的桌面应用程序来完成,但对于 Web 应用程序,您尝试实施的任何锁定方案都只能最大限度地减少损坏,但不能防止损坏。

      不要试图编写一个绝对完美和安全的应用程序。它已经很好了。就用吧,估计根本不会出现这种情况。

      【讨论】:

      • 由于应用程序的性质,肯定会出现这种情况。
      【解决方案4】:

      如果您使用 LINQ to SQL 作为 ORM,它可以使用冲突集合处理更改值的问题。不过,基本上我会同意 Mastermind 的评论。

      【讨论】:

        猜你喜欢
        • 2016-05-23
        • 2020-09-05
        • 2018-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-02
        • 1970-01-01
        • 2021-11-27
        相关资源
        最近更新 更多