IsChanged功能应该在哪里处理?

3
我正在进行内部辩论,讨论在哪里处理数据更改的问题,但无法确定最合理的做法:
1. 在GUI中处理IsChanged - 这需要在页面加载和发布数据之间持久化数据,可能会导致大量带宽/页面交付开销。在Win Forms应用程序中,这并不太糟糕,但在网站中,这可能会对带宽成本产生重大影响。
2. 在DAL中处理 - 这需要多次调用数据库以检查是否有数据更改,这可能意味着额外的不必要的数据库查询,可能导致可扩展性问题。
3. 在Save()存储过程中处理 - 这将要求存储过程潜在地对表进行额外的不必要的调用来进行检查,但会节省DAL对数据库的额外调用。这可能比让DAL处理更具可扩展性,但我的直觉告诉我这可以更好地完成。
4. 在触发器中处理 - 这将需要使用触发器(我情感上很反感,我倾向于避免触发器除非绝对必要)。
5. 根本不处理IsChanged功能 - 不仅难以处理“LastUpdated”日期,而且将数据不必要地保存到数据库似乎本身就是一种不良实践,不利于可扩展性。
因此,每种方法都有其缺点,我不知道哪种是最好的。是否有更可扩展的方法来处理数据持久性,以便查看是否有任何更改?
架构:SQL Server 2005,ASP.NET MVC,IIS7,对于非特定全球受众具有高可扩展性要求。

介意分享一下你的软件背景吗?比如使用场景、数据库、用户群等等。我认为你的观点是有道理的,但在不同的情境/场景下也有利弊之分。 - o.k.w
3个回答

2

我在DAL中处理它 - 它包含原始值,所以不需要访问数据库。


1
根据数据访问层的设计/实现,这些值可能不会被保留,对吧? - o.k.w
这就是为什么我让我的数据访问层保留原始值 - 这是我的设计,当然其他人可能决定不这样做,但对我来说,它一次又一次地得到了回报。 - Otávio Décio
对于 Web 应用程序,我感兴趣的值对象保存在会话中。对于桌面应用程序来说更容易,只要它们在范围内,我就可以使用它们。当我提交更改时,它们将被应用到值对象上,我的数据访问层将比较原始值和当前值,然后为其发出正确的更新语句。 - Otávio Décio
@ocdecio - 所以选项1。 不是GUI本身,而是在该层可用的存储机制之一中。 是这样吗? 您的DAL应该了解会话状态吗? </真诚打算> - John MacIntyre
DAL并不知道它的值对象是否在会话中维护;只要它们处于范围内,它们就具有检索时的状态。由于它们只是值对象,因此可以自由地在各个层之间传递,包括GUI(如果需要)。对它们所做的任何更改都可以进行检查,并由DAL相应地更新存储库。 - Otávio Décio
显示剩余6条评论

2

好的,这里有另一个解决方案 - 我还没有考虑所有的后果,但我认为它可能会起作用:

考虑GetHashCode()比较功能:

在页面加载时,您计算页面数据的哈希码。您将哈希码存储在页面数据或视图状态/会话中,如果您喜欢的话。

在数据发布(回发)时,您计算发布的数据的哈希码并将其与原始哈希进行比较。如果不同,则用户更改了某些内容,您可以将其保存回数据库。

  • 优点
    • 您不必在页面加载时存储所有原始数据,从而减少了带宽/页面传递开销。
    • 您不必让DAL对数据库进行多次调用以确定是否有东西被更改。
    • 仅当有东西被更改时,记录才会在数据库中更新,从而保持正确的LastUpdated日期。
  • 缺点
    • 您仍然需要将任何未存储在“视图状态”中但必须保存有效记录到数据库的业务对象中的原始数据加载到内存中。
    • 更改一个字段将更改哈希值,但您不知道哪个字段,除非您调用来自数据库的原始数据进行比较。 顺便说一句,也许您不需要。 如果您必须更新任何字段,则时间戳会更改,并且覆盖未更改的字段在所有重要目的上没有任何影响。
    • 您无法完全排除碰撞的可能性,但它们将很少发生。 这归结为是否可以接受碰撞的后果?
  • 二选一
    • 如果您将哈希存储在会话中,则可以节省带宽,但会增加服务器资源,因此您需要考虑潜在的可伸缩性问题。
  • 未知
    • 单个列的更新开销与更新多个/所有列的记录的开销是否不同? 我不知道那个性能开销是什么。

考虑到哈希码是1/10^42,而且这个应用程序中的数据并不涉及生死存亡问题,我认为这是一个合理的解决方案。 - BobTheBuilder
我接受了这个答案,因为它似乎是最优解。它将交付开销/带宽降至最低,而不需要在会话中保存不必要的数据并防止数据库中的不必要更新。总体而言,这是解决其他方案可扩展性缺陷的最佳方法。 - BobTheBuilder
@BobTheBuilder - 感谢您的反馈。我也想听听其他人对这种方法的看法,因为我正在考虑在我的下一个项目中使用它,并希望了解潜在的缺点。 - BenAlabaster

0
在您的系统中,为每个实体引入额外的版本字段。有了这个字段,您将能够在数据库级别检查更改。
由于您拥有一个Web应用程序,并且通常Web应用程序需要可扩展性,因此我建议您避免在UI级别使用IsChanged逻辑。在保存操作期间,可以在数据库级别设置LastUpdated日期。

2
我倾向于使用版本字段来处理并发:它并不真正处理“您已更改此记录”,而是处理“自您加载它以来,该记录在数据库中已更改”。 - BobTheBuilder

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