我一直致力于生成各种图表的silverlight应用程序。它需要一些数字运算以及从数据库中获取大量数据。
对于我的数据库通信,我创建了一个使用Linq2SQL的Web服务。为了克服我的网络服务爆炸的问题,我将数据分块,这有时会导致3次网络服务调用。
关于这个问题。当获取更大量的数据时,枚举过程“ ToList()”需要花费几秒钟,这加起来比期望的加载时间长。根据SQL事件探查器,我查询的典型持续时间约为1500。对于1000条记录,ToList()调用最多可能需要4秒钟,这似乎是极端的。
我的主要问题是,有什么办法可以加快这个过程吗?或者是否有更好的方法可以从db获取大量数据到Silverlight应用程序?
其他信息:
我的linq引用被硬编码到我的数据上下文的部分类中。这是由于一个笨拙的存储过程,其返回类型对dbml文件不起作用。
我还创建了一个基本对象,我将其设置为对象的返回类型,主要由快速属性定义组成,例如:
public Guid Id {get; set;}
后续问题是,在定义linq存储过程调用和返回类型时,是否有任何属性可以帮助加快进程,或者我只是将它链接到一个非常基本的对象?
答案 0 :(得分:0)
首先,您需要弄清楚瓶颈在哪里;通常的罪魁祸首:
SELECT
使用SQL跟踪或一些简单的日志记录调查最后两个(LINQ-to-SQL具有DataContext.Log
属性,这在此处非常有用); SQL跟踪可能更准确。
要调查从Silverlight客户端到Web服务器的出行次数是否是问题,请尝试网络跟踪; Fiddler或WireShark应该可以胜任。
如果带宽是问题(即线路上的大量数据),请考虑:
例如,protobuf-net可以与电线上的尺寸产生巨大的差异;但是,要么可能需要稍微不同的代码 - 最简单的方法是在服务上传递byte[]
(如果可能的话,使用MTOM)。
答案 1 :(得分:0)
我猜你已经嵌套了一个linq查询,因此每次向前移动迭代器时,内部查询都会重新运行。如果那是你的情况,也许你想预先计算内部查询。
答案 2 :(得分:0)
答案是完全停止使用ToList()。不要将所有数据加载到Web服务中,然后将其作为一个巨大的blob提供给客户端。采取流式方法;而不是(伪代码)
for each record in query;
add record to list
for each record in list;
create a line of response
write line to response.
你能否像这样流式传输响应?
for each record in query;
create a line of response
write line to response.
您的Web服务中的foreach应该一次查看一条记录的查询结果,并且内存使用量绝对最小。
答案 3 :(得分:0)
要避免使用ToList(),请让您的Web服务代理生成使用List集合的代码。通过在Visual Studio项目中查找服务引用来执行此操作。右键单击>配置服务参考。然后在集合类型下,选择支持linq方法的集合。我使用System.Collection.Generic.List。然后更新服务引用以重新生成References.cs文件。