C# 慢linq枚举
我一直在开发一个silverlight应用程序,它可以生成各种图形。它需要一点数字运算以及从数据库中获取相当数量的数据 对于我的db通信,我创建了一个使用Linq2SQL的web服务。为了克服我的web服务崩溃的问题,我将数据分块,这导致有时有3个web服务调用来获取所有数据 关于这个问题。当获取大量数据时,枚举过程“ToList()”需要很长的几秒钟,这意味着总的加载时间比预期的要长。根据SQL分析器,我的查询的典型持续时间大约为1500。对于1000条记录,ToList()调用最多需要4秒钟,这似乎是极端的 我的主要问题是,有什么办法可以加快这一进程?或者,有没有更好的方法将大量数据从数据库传输到silverlight应用程序 其他信息: 我的linq引用被硬编码到我的数据上下文的部分类中。这是由于一个笨拙的存储过程,它的返回类型不能很好地处理dbml文件 我还创建了一个基本对象,将其设置为对象的返回类型,主要由以下快速特性定义组成:C# 慢linq枚举,c#,linq,silverlight,C#,Linq,Silverlight,我一直在开发一个silverlight应用程序,它可以生成各种图形。它需要一点数字运算以及从数据库中获取相当数量的数据 对于我的db通信,我创建了一个使用Linq2SQL的web服务。为了克服我的web服务崩溃的问题,我将数据分块,这导致有时有3个web服务调用来获取所有数据 关于这个问题。当获取大量数据时,枚举过程“ToList()”需要很长的几秒钟,这意味着总的加载时间比预期的要长。根据SQL分析器,我的查询的典型持续时间大约为1500。对于1000条记录,ToList()调用最多需要4秒钟
接下来的问题是,在定义linq存储过程调用和返回类型时,是否有任何属性可以帮助加快进程,或者我是否可以将其链接到一个非常基本的对象?首先,您需要找出瓶颈在哪里;惯犯:
- 潜伏期;你提到了3个电话(而不是300个),所以我认为这不是问题所在
- 带宽;您要发送的对象有多胖
- 核心数据库查询性能;您的
选择的速度有多快
- 延迟加载问题;你真的在做n+1db的操作吗
DataContext.Log
属性,在这里非常有用)来研究最后两个问题;SQL跟踪可能更准确
要调查从Silverlight客户端到web服务器的旅行次数是否是问题所在,请尝试网络跟踪;小提琴手或线鲨应该做这项工作
如果带宽是一个问题(即大量数据通过线路传输),则考虑:
- 压缩
- 不同的序列化程序
例如,protobuf网络可以对导线上的尺寸产生巨大的差异;不过,这两种方法都可能需要稍有不同的代码—最简单的方法是在服务上传递
字节[]
(如果可能的话,使用MTOM)。我猜您已经嵌套了一个linq查询,所以每次向前移动迭代器时,内部查询都会重新运行。如果您的情况是这样的,可能需要预先计算内部查询。答案是完全停止使用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.
web服务中的foreach应该一次遍历一条记录的查询结果,并且内存使用量将是绝对最小的。为了避免使用ToList(),请让web服务代理生成使用列表集合的代码。通过在VisualStudio项目中查找服务引用来实现这一点。右键单击>配置服务引用。然后在集合类型下,选择支持linq方法的集合。我会使用System.Collection.Generic.List。然后更新服务引用以重新生成References.cs文件。当您说“枚举最多需要4秒”时,您的确切意思是什么?这里有很多可能成为瓶颈的地方。为了理智起见,我建议你把它们完全分开,这样我们就知道发生了什么。如果我有点罗嗦的话,对不起。我的意思是,在我调用存储过程之后,我的ToList()调用可能需要几秒钟,这似乎有点多。伙计,在这段时间内创建了多少个对象?当您调用ToList()时,您是在创建数十个对象还是数千个对象?我将数据分成1000个块。我跳过(1000*packetNo).Take(1000).ToList()准确地说。最多应该是1000个对象。我在本地移动了db,这将事物放入透视图中。在db穿过云层并花了大约4秒的时间回复我之前。我还列举了所有3000多行,而我只拿了1000行。从长远来看,每次对db的调用都会超过一秒,而对web服务的往返调用则会超过2秒。还不算太坏,但更高的权力要求更高的速度。我唯一能想到的就是想办法一次获取所有数据。这就引出了一个新的问题
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.