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

问题描述 投票:0回答:1

我们有一个 WCF 服务,用于查询底层数据存储(现在是 SQL Server 2005)。该服务可能会返回相当大量的数据;我们的实体类有 60000 多个实例,其中包含约 20 个属性。这些属性大多是基元,例如 string、int、DateTime,其中一些属性指向其他实体,而这些实体又可能指向其他实体;不过这些层次结构并不是很深。

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

我们想要做的是引入某种“分页”功能,客户端可以调用服务并获取一定数量的实例,然后再次调用并获取下一个块,依此类推,直到完整结果是取来的。由于没有大量使用 WCF,我不太确定实现这一目标的最佳方法。

也许要记住的一件事是,在获取块时底层数据很可能会发生变化。我不太确定这对我们来说是否是一个问题(需要对此进行一些调查),但可能是,因此也欢迎任何有关处理该特定情况的意见。

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

那么,简而言之,问题是:对于这种情况是否有最佳实践(或者我们应该注意的任何绝对禁忌)?

.net wcf pagination
1个回答
9
投票

在客户端和服务器上使用流式绑定配置,并使用仅具有流 [MessageBodyMember](以及作为 [MessageHeader] 发送的任何其他元数据)的 MessageContract,可以让您在一次调用中完成整个操作,而无需担心分页(只需使用服务器端的枚举器来提供流并处理出现在客户端上的各个实体),但是您必须在流中滚动自己的框架(例如,使用 DataContractSerializer 或其他方式在流上手动序列化/反序列化实体) 。我已经这样做了,效果很好,但有点痛苦。

如果您想要进行分页,最简单的方法是将会话 WCF 通道与快照事务结合使用(如果您使用 SQL Server 或其他支持它们作为实体源的东西)。在第一个请求上启动快照 tx,然后将 tx 的生命周期与会话联系起来,这样您就可以看到页面请求之间数据的稳定图片 - 当会话关闭时(或多次),tx 将被释放出,如果客户端意外断开连接)。然后客户端请求它看到的最后一个键值+它想要多少条记录(注意 maxReceivedMessageSize - 留下大量的空间)。由于您处于快照中,因此您不必担心更改 - 您将在转储期间看到一致的视图。如果您无法对源数据进行快照以防止其在下载过程中发生更改,那么生活就会困难得多。总是可行的,但为此进行设计是针对数据的。

© www.soinside.com 2019 - 2024. All rights reserved.