2009-09-22 86 views
1

我一直在Silverlight应用程序生成各种图表。它需要一些数字处理以及从数据库中获取相当数量的数据。慢linq枚举

对于我的数据库通信,我创建了一个使用Linq2SQL的Web服务。为了克服我的Web服务爆炸的问题,我将数据分块,有时会有3个Web服务调用来完成这些。

谈到这个问题。当获得大量的数据时,枚举过程“ToList()”花费很长时间,这加起来比期望的加载时间长。根据SQL Profiler,我的查询的典型持续时间约为1500。对于1000条记录来说,ToList()调用最多可能需要4秒钟,这看起来极端。

我的主要问题是,有什么可以做的,以加快这一进程?或者,有没有更好的方法从数据库获取大量数据到Silverlight应用程序?

附加信息:

我的LINQ参考硬编码到一个局部类我的数据上下文。这是由于一个尴尬的存储过程,它的返回类型与dbml文件无法兼容。

我也创建了我设定的返回类型为我的对象基本对象,主要包含如快速的属性定义:

public Guid Id {get; set;}

的跟进问题是,定义一个LINQ存储过程调用时和返回类型,是否有任何有助于加速进程的属性,或者我很好地将它链接到一个非常基本的对象?

+2

当你说“枚举可能需要4秒”时,你究竟是什么意思?你有很多可能成为瓶颈的地方。为了理智,我建议你把它们完全分开,这样我们就知道发生了什么。 – 2009-09-22 19:47:03

+0

对不起,如果我有点罗嗦。 我的意思是我调用存储过程后,我的ToList()调用可能需要几秒钟,这似乎有点多。 – 2009-09-22 19:52:30

+0

好友,那个时候正在创建多少个对象?当你调用ToList()时,你创建了数十个对象还是数千个? – 2009-09-22 20:13:17

回答

0

首先你需要弄清瓶颈在哪里;通常的罪魁祸首:

  • latency;你提到调用(而不是300),所以我不认为这是问题
  • 带宽;你想发送多少对象
  • 核心数据库查询性能;你的速度有多快SELECT
  • 延迟加载问题;你真的在做n + 1分贝操作吗?

用SQL跟踪或一些简单的日志记录(LINQ-to-SQL有DataContext.Log属性,在这里非常有用)调查最后两个;一个SQL跟踪可能更准确。

要调查从Silverlight客户端到Web服务器的旅行次数是否是问题,请尝试网络跟踪; Fiddler或WireShark应该完成这项工作。

如果带宽是问题(即,在导线的数据)的纯粹的散装,然后考虑:

  • 压缩
  • 不同的串行

例如,protobuf网可以使巨大差异电线上的大小;或者可能需要稍微不同的代码 - 最简单的方法是将byte[]通过服务(如果可能,则使用MTOM)。

+0

我在本地移动了数据库,将事物置于透视之中。在数据库通过云端之前,大约需要4秒钟才能找到我。我还列举了所有3000多行,当我只用1000时。从长远来看,每次拨打电话给我的分机号码稍微超过一秒钟,并且我的网络往返呼叫有点超过2秒钟服务。不错,但更高的力量想要更多的速度。唯一我能想到的是试图找到一种方法来一次获得所有的数据。这导致了一个新的问题在http://stackoverflow.com/questions/1462452/silverlight-data-access – 2009-09-22 20:56:07

0

我猜你已经嵌套了linq查询,所以每次你将迭代器向前移动时,内部查询就会重新运行。也许你想要预先计算内部查询,如果这是你的情况。

0

答案是完全停止使用ToList()。不要将所有数据加载到Web服务中,然后将其作为一个巨大的数据块提供给客户端。采取流式方法;所以,而不是(伪代码)

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应逐步查询一条记录的结果,并且内存使用量将绝对最小。

0

为避免必须使用ToList(),请让Web服务代理生成使用List集合的代码。通过在Visual Studio项目中查找服务引用来完成此操作。右键单击>配置服务参考。然后在集合类型下,选择一个支持linq方法的集合。我会使用System.Collection.Generic.List。然后更新服务引用以重新生成References.cs文件。