缓慢的linq枚举

时间:2009-09-22 19:45:14

标签: c# linq silverlight

我一直致力于生成各种图表的silverlight应用程序。它需要一些数字运算以及从数据库中获取大量数据。

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

关于这个问题。当获取更大量的数据时,枚举过程“ ToList()”需要花费几秒钟,这加起来比期望的加载时间长。根据SQL事件探查器,我查询的典型持续时间约为1500。对于1000条记录,ToList()调用最多可能需要4秒钟,这似乎是极端的。

我的主要问题是,有什么办法可以加快这个过程吗?或者是否有更好的方法可以从db获取大量数据到Silverlight应用程序?

其他信息:

我的linq引用被硬编码到我的数据上下文的部分类中。这是由于一个笨拙的存储过程,其返回类型对dbml文件不起作用。

我还创建了一个基本对象,我将其设置为对象的返回类型,主要由快速属性定义组成,例如:

 public Guid Id {get; set;} 

后续问题是,在定义linq存储过程调用和返回类型时,是否有任何属性可以帮助加快进程,或者我只是将它链接到一个非常基本的对象?

4 个答案:

答案 0 :(得分:0)

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

  • 等待时间;你提到 3 电话(而不是300),所以我认为这不是问题
  • 带宽;你要发送的对象有多胖?
  • 核心数据库查询性能;您SELECT
  • 的速度有多快
  • 延迟加载问题;你实际上在进行n + 1 db操作吗?

使用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文件。