【发布时间】:2017-11-30 21:20:34
【问题描述】:
我的控制器中有一个函数,可以为 Linq 查询结果集下载 csv 文件。 linq 查询只是从数据库中获取用户提供的日期范围的数据。
var dataForDateRange = obj.table.Where(m => m.id== id && m.CreatedDateTime >= start && m.CreatedDateTime<= end);
string csv = string.Empty;
foreach(var csvData in dataForDateRange)
{
csv = csvData.col1 + "," + csvData.col2 + "," + csvData.col3......;
csv += "\r\n";
}
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename="+engineName+"_CSV.csv");
Response.Charset = "";
Response.ContentType = "application/text";
Response.Output.Write(csv);
Response.Flush();
Response.End();
上面的代码成功地适用于较少数量的数据行。如果记录超过 10000,则浏览器超时。调试显示代码在 foreach 循环处挂起。 为大约 500000 条记录完成这项工作的最佳方法是什么?
【问题讨论】:
-
对于初学者,您可能希望在构建
csv文件时切换到使用 StringBuilder。您的代码现在的方式可能会创建数千个临时字符串。 -
我会将其转换为从那里使用数据表我会使用 lambda 语句使用数据表将其快速导出到 csv .. 这要快得多..
-
@pstrjds
He has terabytes of memory clearly, efficiency is for chumps. -
对于这样的情况,我会推荐一种不同的方法。让用户触发请求,在后台处理它,监控完成,将文件保存在您的服务器中,并在文件准备好时提供一个链接,以便用户下载。
-
@Greg - 这不仅仅是内存压力,还有一个性能问题。虽然粗略计算,如果只有 4 列,每列 10 个字符的数据,在 500000 行中,我们正在查看大约 40 MB 的文件。因此,即使使用
StringBuilder,也不确定这是一个好方法。