Asp.net 按需在服务器中生成并提供文件。不消耗太多资源的最佳方法?
我的应用程序必须将存储过程的结果导出为.csv格式。基本上,客户机执行一个查询,他可以在一个分页的网格上看到结果,如果它包含他想要的内容,然后他点击“导出到CSV”按钮,下载整个内容 服务器必须运行一个存储过程,该过程将返回完整的结果,而无需分页,创建文件并将其返回给用户 结果文件可能非常大,因此我想知道在服务器上按需创建此文件并将其提供给客户端而不占用服务器内存或资源的最佳方法是什么 最简单的方法:使用LINQ调用存储过程,创建一个流并迭代结果集合,并在文件中为每个集合项创建一行Asp.net 按需在服务器中生成并提供文件。不消耗太多资源的最佳方法?,asp.net,asp.net-mvc,file,asp.net-mvc-3,linq-to-sql,Asp.net,Asp.net Mvc,File,Asp.net Mvc 3,Linq To Sql,我的应用程序必须将存储过程的结果导出为.csv格式。基本上,客户机执行一个查询,他可以在一个分页的网格上看到结果,如果它包含他想要的内容,然后他点击“导出到CSV”按钮,下载整个内容 服务器必须运行一个存储过程,该过程将返回完整的结果,而无需分页,创建文件并将其返回给用户 结果文件可能非常大,因此我想知道在服务器上按需创建此文件并将其提供给客户端而不占用服务器内存或资源的最佳方法是什么 最简单的方法:使用LINQ调用存储过程,创建一个流并迭代结果集合,并在文件中为每个集合项创建一行 问题1:延迟
.ToArray
,它会逐项给我结果吗?).Dispose
/.Close
之前,该流是否一直保存在RAM内存中您所说的并不是真正的延迟执行,而是限制查询结果。当您说
objectCollection.Take(10)
时,迭代可枚举项时生成的SQL只获取该查询的前10个结果
也就是说,存储过程将返回返回的任何结果,无论是5行还是5000行数据。对结果执行.Take()不会限制数据库返回的内容
因此,我的建议(如果您的场景可能的话)是将分页参数添加到存储过程中(页码、页面大小)。这样,您将只返回您计划使用的结果。然后,当您想要CSV的完整列表时,您可以传递一个较大的页面大小,或者使用空值表示“全选”。我知道我在这里玩游戏迟到了,但理论上我们在这里谈论多少记录?我看到5000人被扔来扔去,如果它在那里,那对你的服务器来说应该不是问题 回答最简单的方法:
写入流是一种方法,因为它消耗的内存不会超过当前的“记录”和相关内存。该流可以是文件流(如果您创建文件)或ASP.NET流(如果您直接写入web),也可以是任何其他有用的流 创建文件(使用FileStream)的优点是能够缓存数据以反复满足相同的请求。根据您的需要,这可能是一个真正的好处。您必须想出一种智能算法来根据输入确定文件路径和名称。这将是缓存密钥。一旦您有了一个文件,您就可以使用api,它利用了Windows内核缓存,并且通常非常高效。您还可以使用HTTP客户端缓存(如
自
以来上次修改的头等),因此下次客户端请求相同的信息时,您可以返回未修改的
(HTTP 304状态代码)响应。使用缓存文件的缺点是需要管理这些文件、磁盘空间、过期时间等
现在,Linq或IDataReader在性能或内存消耗方面不应该有太大的改变,只要您不使用具体化整个数据(耗尽流)或其中很大一部分的Linq方法。这意味着您需要避免ToArray()、ToList()方法和其他类似的方法,而只关注“流式”方法(枚举、跳过、while等)。我认为他还关心准备下载时内存中CSV的大小。是的,这是可以理解的。如果他想分页结果以避免内存问题,他也可以使用分页参数生成CSV。这就是@Keith的问题,我无法分页,因为文件必须有完整的结果:)分页已经在预览屏幕中实现。我所关心的是gangelo所指出的。@vtortola-我认为keith所说的是使用分页alread读取“页面”或“块”中的数据