第 2 章 — 处理数据
在智能客户端中,可在客户端上使用应用程序数据。要使您的智能客户端有效工作,很重要的一点是对该数据进行适当的管理,以确保其有效、一致和安全。
可以通过服务器端应用程序(例如,通过 Web 服务)向客户端提供应用程序数据,或者应用程序可以使用它自己的本地数据。如果数据是由应用程序提供的,则智能客户端应用程序可以缓存数据以改善性能或者支持脱机使用。在这种情况下,您需要决定客户端应用程序应该如何处理就该服务器而言已经过时的数据。
如果智能客户端应用程序提供在本地修改数据的能力,则必须在以后将客户端更改与服务器端应用程序进行同步。在这种情况下,您必须决定客户端应用程序如何处理数据冲突,以及如何跟踪需要发送到服务器的更改。
在设计您的智能客户端应用程序时,您需要认真考虑这些问题以及其他许多问题。本章分析了在客户端上处理数据时的各种注意事项,包括:
数据类型。
缓存数据。
数据并发。
使用
ADO.NET 数据集来管理数据。
Windows
窗体数据绑定。
本章未讨论其他许多与处理数据有关的问题。具体说来,在第 5 章:安全性注意事项中讨论了数据处理安全性问题,在第
4 章:偶尔连接的智能客户端中讨论了脱机注意事项。
数据类型
智能客户端通常必须处理两种类别的数据:
只读引用数据
瞬态数据
通常情况下,需要以不同的方式处理这些类型的数据,因此更详细地分析一下每种类型将是很有用的。
只读引用数据
只读引用数据是不会由客户端更改并且被客户端用于引用目的的数据。因此,从客户端的观点看来,该数据为只读数据,并且客户端不会对其执行更新、插入或删除操作。只读引用数据很容易在客户端上进行缓存。引用数据在智能客户端应用程序中具有许多种用途,包括:
提供静态引用或查找数据。这方面的示例包括产品信息、价格表、发货选项和价格。
支持数据验证,允许检查用户输入数据的正确性。示例有针对交货时间表检查输入的日期。
帮助与远程服务进行通讯。示例在本地将用户选择转化为产品 ID,然后将该信息发送到 Web 服务。
呈现数据。示例包括呈现帮助文本或用户界面标签。
通过在客户端上存储和使用引用数据,您可以减少需要从客户端传输到服务器的数据量,改善应用程序的性能,帮助启用脱机功能,并提供早期数据验证以提高应用程序的可用性。
尽管客户端无法更改只读引用数据,但可以在服务器上进行更改(例如,由管理员或超级用户更改)。您需要确定在发生数据更改时用于更新客户端的策略。此类策略可能涉及到在发生更改时将更改推到客户端上,或者按照特定的时间间隔或在客户端上执行某些操作之前从服务器拉入更改。但是,因为数据在客户端上是只读的,所以您无须跟踪客户端更改。这就简化了需要对只读引用数据进行处理的方式。
缓存数据
智能客户端通常需要在本地缓存数据(无论是只读引用数据还是瞬态数据)。通过缓存数据,有可能改善应用程序的性能并提供脱机工作所需的数据。但是,您需要认真考虑在客户端缓存哪些数据、如何管理这些数据以及可以在哪个上下文中使用这些数据。
要启用数据缓存,您的智能客户端应用程序应该实现某种形式的缓存基础结构,以便透明地处理数据缓存细节。您的缓存基础结构应该包括下列缓存机制中的一种或两种:
短期数据缓存。在内存中缓存数据对性能有益,但不能持久,因此您可能需要在重新运行应用程序时从源拉入数据。这样做可能会妨碍您的应用程序脱机操作。
长期数据缓存。通过在持久性媒体(如独立存储或本地文件系统)中缓存数据,可以在没有连接到服务器时使用应用程序。您可以选择将长期存储与短期存储结合起来以改善性能。
无论您采用哪种缓存机制,都应该确保仅将用户有权访问的数据提供给客户端。而且,在客户端缓存的敏感数据要求进行认真处理以确保它的安全。因此,您可能需要在将数据传输到客户端以及在客户端存储数据时,对数据进行加密。有关详细信息,请参阅第
5 章:安全性注意事项中的“处理敏感数据”。
当您设计智能客户端以支持数据缓存时,您应该考虑为客户端提供一种请求新数据的机制,而无论缓存的状态如何。这意味着您可以确保应用程序随时能够执行新的事务,并且不会使用过时的数据。您还可以将客户端配置为预先获取数据,以便减少在缓存数据到期时处于脱机状态的风险。
只要有可能,您都应该将某种形式的元数据与该数据关联起来,以便使客户端能够以聪明的方式管理这些数据。此类元数据可用于指定数据的标识和任何约束,或者指定所需的与该数据关联的行为。您的客户端缓存基础结构应该消耗该元数据,并且使用它来适当处理缓存的数据。
客户端缓存的所有数据都应该是可以唯一标识的(例如,通过版本号或日期戳),以便在确定是否需要更新数据时,可以正确地识别相应的数据。这样,您的缓存基础结构就能够询问服务器它所具有的数据当前是否有效,并且确定是否需要进行更新。
元数据还可以用来指定与缓存数据的使用和处理相关的约束或行为。示例包括:
时间约束。这些约束指定可以使用缓存数据的时间或日期范围。当该数据过时或到期时,可以将其从缓存中丢弃,或者通过从服务器获取最新数据来自动刷新数据。在某些情况下,合适的做法可能是让客户端使用过时的引用数据,并且在与服务器进行同步时将过时数据映射到最新数据。
地理约束。某些数据可能仅适用于特定地区。例如,您可能对于不同的地点有不同的价格表。可以使用您的缓存基础结构分别针对不同的地点来访问和存储数据。
安全性要求。可以将专门提供给特定用户的数据加密,以确保只有相应的用户可以访问这些数据。在此情况下,所提供的数据已经进行了加密,并且用户必须向缓存基础结构提供凭据以便对数据进行解密。
业务规则。您可能拥有与缓存数据关联的业务规则,用来规定如何使用这些数据。例如,您的缓存基础结构可能考虑用户的角色,以便确定向该用户提供哪些数据以及如何处理这些数据。
数据并发
正如前面所提到的,使用智能客户端的一个问题是:在将任何客户端更改与服务器进行同步之前,服务器上保存的数据可能发生更改。您需要采用某种机制来确保在对数据进行同步时,数据冲突能够得到适当的处理,并且最后得到的数据是一致和正确的。数据能够由多个客户端进行更新的能力称为“数据并发”。
您可以使用两种方法来处理数据并发:
? 保守式并发。保守式并发允许一个客户端保持数据上的锁,以禁止任何其他客户端修改数据,直至客户端自己的更改完成为止。在这种情况下,如果另一个客户端尝试修改数据,则在锁的拥有者释放该锁之前,这些尝试将失败或者被阻止。
? 保守式并发可能有问题,因为单个用户或客户端可能由于疏忽而长时间地保持锁定。所以,该锁可能会妨碍重要资源(如数据库行或文件)及时得到释放,从而严重影响应用程序的可伸缩性和可用性。但是,当您需要完全控制对重要资源所做的更改时,保守式并发可能是适当的。请注意,如果您的客户端要脱机工作,则不能使用这种并发,因为客户端无法对数据加锁。
? 开放式并发。开放式并发不会锁定数据。要判断是否实际需要更新,可以将原始数据随更新请求和已更改的数据一起发送。随后,将针对当前数据检查原始数据,以查看是否同时对原始数据进行了更新。如果原始数据和当前数据匹配,则执行更新;否则,拒绝请求,并产生开放式失败。要优化该过程,您可以在数据中使用时间戳或更新计数器,而不必发送原始数据,此时只需要检查时间戳或计数器。
开放式并发提供了一种良好的机制,可用来更新不会非常频繁更改的主数据,如客户的电话号码或地址。开放式并发允许每个人读取数据,在发生更新的概率小于读取操作的情况下,开放式失败的风险或许是可以接受的。在数据频繁更改以及开放式更新可能经常失败的情况下,开放式并发可能并不适合。
在大多数智能客户端方案(包括客户端将要脱机工作的方案)中,开放式并发是正确的方法,因为它允许多个客户端同时使用数据,而不会不必要地锁定数据和影响所有其他客户端。
使用 ADO.NET 数据集来管理数据
DataSet 是一个表示一个或多个关系数据库表的对象。数据集在断开连接的缓存中存储数据。DataSets的结构与关系数据库类似:它公开了一个由表、行和列组成的层次结构对象模型。另外,它还包含为DataSets定义的约束和关系。
ADO.NET DataSet 包含零个或更多个由 DataTable 对象表示的表组成的集合。DataTable
在 System.Data 命名空间中定义,并且表示单个由内存驻留数据组成的表。它包含由 DataColumnCollection
表示的列和由 ConstraintCollection 表示的约束组成的集合,它们共同定义了该表的架构。DataTable
还包含由 DataRowCollection(它包含该表中的数据)表示的行组成的集合。与其当前状态一起,DataRow
保留其当前版本和原始版本,以便标识对该行中存储的值所做的更改。
DataSets可以强类型化或非类型化。类型化的 DataSet 从 DataSet 基类继承,但是向 DataSet
中添加了强类型化的语言功能,从而使用户可以用更加强类型化的编程方式访问内容。在生成应用程序时,可以使用任一种类型。但是,Microsoft
Visual Studio ? 开发系统对类型化DataSets具有更多支持,它们使得用DataSets编程变得更加容易,而且更不容易出错。
DataSets在智能客户端环境中尤其有用,因为它们提供了能够帮助客户端在脱机状态下使用数据的功能。它们可以跟踪对数据进行的本地更改,这有助于与服务器同步数据以及协调数据冲突,并且它们还可用于合并来自不同源的数据。
Windows 窗体数据绑定
通过 Windows 窗体数据绑定,您可以将应用程序的用户界面连接到该应用程序的基础数据。Windows
窗体数据绑定支持双向绑定,因此您可以将数据结构绑定到用户界面,向用户显示当前数据值,使用户可以编辑数据,然后使用用户输入的值自动更新基础数据。
您可以使用 Windows 窗体数据绑定将几乎任何数据结构或对象绑定到用户界面控件的任何属性。您可以将单个数据项绑定到控件的单个属性,还可以将更为复杂的数据(例如,数据项集合或数据库表)绑定到该控件,以便它可以在数据网格或列表框中显示所有数据。
注 您可以绑定任何支持一个或多个公共属性的对象。您只能绑定到类的公共属性而不是公共成员。
通过 Windows 窗体数据绑定,您可以随您的应用程序一起提供灵活的、数据驱动的用户界面。您可以使用数据绑定提供对用户界面外观的自定义控制(例如,通过绑定到某些控件属性,如背景或前景颜色、大小、图像或图标)。
数据绑定具有许多种用途。例如,可以使用它完成下列任务:
向用户显示只读数据。
使用户可以从用户界面更新数据。
提供数据上的主从视图。
使用户可以浏览复杂的相关数据项。
提供查找表功能,使用户界面可以连接用户友好的显示名称。
|