Asp.net 按需在服务器中生成并提供文件。不消耗太多资源的最佳方法?

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:延迟

我的应用程序必须将存储过程的结果导出为.csv格式。基本上,客户机执行一个查询,他可以在一个分页的网格上看到结果,如果它包含他想要的内容,然后他点击“导出到CSV”按钮,下载整个内容

服务器必须运行一个存储过程,该过程将返回完整的结果,而无需分页,创建文件并将其返回给用户

结果文件可能非常大,因此我想知道在服务器上按需创建此文件并将其提供给客户端而不占用服务器内存或资源的最佳方法是什么

最简单的方法:使用LINQ调用存储过程,创建一个流并迭代结果集合,并在文件中为每个集合项创建一行

  • 问题1:延迟执行是否也适用于LINQ到存储过程?(我的意思是,.NET会尝试创建一个包含内存中结果集中所有项的集合吗?或者如果我进行迭代而不是
    .ToArray
    ,它会逐项给我结果吗?)

  • 问题2:在我执行
    .Dispose
    /
    .Close
    之前,该流是否一直保存在RAM内存中

  • 不那么简单的方法:使用IDataReader调用存储过程,每行直接写入HTTP响应流。这看起来是一个很好的方法,只要我读我写的响应,内存就不会被破坏

    真的值得吗

    我希望我的解释是正确的

    提前谢谢

    “服务器必须运行一个存储过程,该过程将返回完整的结果,而无需分页…”

    也许不是,但我相信你需要Silverlight

    您可以设置一个web服务或控制器,允许您“按页面”检索数据(非常类似于使用GridView或其他中继器调用“分页”服务)。您可以从silverlight进行异步调用以获取每个“页面”的数据,直到完成,然后使用SaveFileDialog保存到硬盘

    希望这有帮助

    |

    您所说的并不是真正的延迟执行,而是限制查询结果。当您说
    objectCollection.Take(10)
    时,迭代可枚举项时生成的SQL只获取该查询的前10个结果

    也就是说,存储过程将返回返回的任何结果,无论是5行还是5000行数据。对结果执行.Take()不会限制数据库返回的内容


    因此,我的建议(如果您的场景可能的话)是将分页参数添加到存储过程中(页码、页面大小)。这样,您将只返回您计划使用的结果。然后,当您想要CSV的完整列表时,您可以传递一个较大的页面大小,或者使用空值表示“全选”。

    我知道我在这里玩游戏迟到了,但理论上我们在这里谈论多少记录?我看到5000人被扔来扔去,如果它在那里,那对你的服务器来说应该不是问题

    回答最简单的方法:

  • 除非您另外指定(您禁用延迟加载),否则它会这样做

  • 我不知道你在问什么。您是指用于创建文件的streamreader,还是指用于调用SP的datacontext?我相信datacontext会在您完成后为您清理干净(无论如何关闭都是很好的做法)。Streamreader等需要运行dispose方法才能从内存中删除

  • 也就是说,在处理文件导出时,我在过去成功地以编程方式(通过迭代)构建了表(CSV),然后以HTTP响应的形式发送结构化数据,类型在标题中指定,这并不像您所说的那样简单:)。以下是一个问题,询问如何使用CSV进行此操作:


    写入流是一种方法,因为它消耗的内存不会超过当前的“记录”和相关内存。该流可以是文件流(如果您创建文件)或ASP.NET流(如果您直接写入web),也可以是任何其他有用的流

    创建文件(使用FileStream)的优点是能够缓存数据以反复满足相同的请求。根据您的需要,这可能是一个真正的好处。您必须想出一种智能算法来根据输入确定文件路径和名称。这将是缓存密钥。一旦您有了一个文件,您就可以使用api,它利用了Windows内核缓存,并且通常非常高效。您还可以使用HTTP客户端缓存(如
    以来上次修改的头等),因此下次客户端请求相同的信息时,您可以返回
    未修改的
    (HTTP 304状态代码)响应。使用缓存文件的缺点是需要管理这些文件、磁盘空间、过期时间等


    现在,Linq或IDataReader在性能或内存消耗方面不应该有太大的改变,只要您不使用具体化整个数据(耗尽流)或其中很大一部分的Linq方法。这意味着您需要避免ToArray()、ToList()方法和其他类似的方法,而只关注“流式”方法(枚举、跳过、while等)。

    我认为他还关心准备下载时内存中CSV的大小。是的,这是可以理解的。如果他想分页结果以避免内存问题,他也可以使用分页参数生成CSV。这就是@Keith的问题,我无法分页,因为文件必须有完整的结果:)分页已经在预览屏幕中实现。我所关心的是gangelo所指出的。@vtortola-我认为keith所说的是使用分页alread读取“页面”或“块”中的数据