如何仅更新MVC中已更改的模型的属性?

时间:2009-05-18 15:15:50

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

我正在开发一个允许编辑记录的webapp。两个用户可能同时在同一个屏幕上工作,如果他们都点击保存,我想尽量减少损坏。

如果User1请求该页面,然后更改地址,电话和联系人详细信息,但在他单击“保存”之前,User2请求同一页面。

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

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

是否有处理此问题的模式我不知道?

你会怎么处理它?<​​/ p>

更新:在回答以下评论时,我正在使用实体框架。

安东尼

4 个答案:

答案 0 :(得分:3)

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

您执行的每次更新都应检查记录是否在此期间未发生变化。

所以:

  1. 在记录上放置一个整数“version”属性或guid / rowversion。
  2. 确保它包含在html中的隐藏字段中,因此随任何提交一起返回;
  3. 执行更新时,请确保(数据库)记录的版本/ guid / rowversion仍然与隐藏字段中的值匹配[并在您进行更新时将“1”添加到“版本”整数中决定采用那种手动方式。]
  4. 类似的方法显然是在记录上使用日期/时间戳,但不要这样做,因为在系统时钟的准确性范围内,它是有缺陷的。

    [我建议你会在其他地方找到更全面的解释。当然,如果您要谷歌获取有关NHibernate版本功能的信息......]

答案 1 :(得分:0)

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

另一个选项可能是将所有修订存储在数据库中,因此当两个用户提交时,两个副本都会保存并仍然存在。从那以后,你需要做的就是合并两者。

答案 2 :(得分:0)

您通常不会处理此问题。如果两个用户碰巧同时编辑文档并提交更新,则其中一个用户获胜而另一个用户失败。

资源锁定可以通过有状态桌面应用程序完成,但是对于Web应用程序,您尝试实施的任何锁定方案可能只会最小化损坏但不会阻止它。

不要试图写出绝对完美和安全的应用程序。它已经很好了。只要使用它,可能情况根本不会出现。

答案 3 :(得分:0)

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