代码之家  ›  专栏  ›  技术社区  ›  Fredrik Mörk

具有大量数据的WCF服务的最佳实践?

  •  9
  • Fredrik Mörk  · 技术社区  · 15 年前

    我们有一个用于查询基础数据存储的WCF服务(现在是SQL Server 2005)。此服务可能返回大量数据;60000多个包含约20个属性的实体类实例。这些属性主要是一些原语,如字符串、int、datetime,其中一对指向其他实体,而其他实体又可能指向其他实体;不过,这些层次结构并不是很深。

    一个使用此服务的应用程序通常只返回合理数量的实体(从几个实例到几千个实例)进行查询。但有时它会进行一个查询,返回大量数据,如前所述(它需要处理这些数据,因此缩小查询条件不是一个选项)。

    我们要做的是引入某种“分页”功能,在这种功能中,客户机可以调用服务并返回一定数量的实例,然后再次调用并获取下一个块等,直到获取完整的结果为止。我没有在WCF工作太多,我不太确定实现这一目标的最佳方法。

    可能要记住的一点是,在获取块时,底层数据可能会发生很大的变化。我不太确定这对我们来说是否是一个问题(需要调查一下这个问题),但它可能是,所以任何处理这种特殊情况的投入都是受欢迎的。

    我们已经开始研究流式处理响应,但也希望看到分页示例,因为我们可能希望在收到完整结果之前开始处理数据。

    那么,简而言之,问题是:对于这种情况(或者我们应该知道的任何绝对不存在)有没有最佳实践?

    1 回复  |  直到 15 年前
        1
  •  9
  •   nitzmahone    15 年前

    在客户端和服务器上使用只有流[messagebodymember]的messagecontract(以及作为[messageheader]发送的任何其他元数据)的流绑定配置,可以让您在一次调用中完成整个操作,而不必担心分页(只需使用服务器端的枚举器来提供流并将单个实体作为ey出现在客户机上),但您必须在流中滚动自己的帧(例如,使用DataContractSerializer或其他方法在流上手动序列化/反序列化实体)。我做过,效果很好,但有点疼。

    如果要进行分页,最简单的方法是将sessionful wcf通道与快照事务结合使用(如果您使用的是SQL Server或其他支持它们的实体源)。在第一个请求上启动快照tx,然后将tx的生命周期绑定到会话,这样您就可以看到页面请求之间的数据的稳定图片-会话关闭时(或者如果客户端意外断开连接,则超时),将释放tx。然后,客户机请求它看到的最后一个键值+它需要多少记录(注意maxReceivedMessageSize-留出大量空间)。因为您在快照中,所以不必担心更改——在转储期间,您将看到一个一致的视图。如果你不能快照你的源数据来防止它在下载过程中发生变化,那么生活就更困难了。总是可行的,但是为它设计是非常具体的数据。