我有一个DataTable
,可以在其中放置数十万条记录。这是一个巨大的内存开销,所以我添加了一个功能,用户只能在我的应用程序中可视化前200个记录,并可以将其余结果导出到CSV文件。
但是,为了导出到CSV文件,我使用的方法是将DataTable
的内容转换为CSV文件。由于我可以在DataTable中拥有超过100K的记录,我认为将所有记录放入DataTable并映射到CSV文件会占用大量内存。建议采用什么方法?这是我的CSV映射代码:
StringBuilder builder = new StringBuilder();
IEnumerable<string> columnNames = dtResults.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
builder.AppendLine(string.Join(",", columnNames));
foreach (DataRow row in dtResults.Rows)
{
IEnumerable<string> fields = row.ItemArray.Select(field => DisplayCommas(field.ToString()));
builder.AppendLine(string.Join(",", fields));
}
File.WriteAllText(filename, builder.ToString());
答案 0 :(得分:0)
我上学并使用sqlcmd。类似的东西:
sqlcmd -q "select field1,field2,field3 from mytable" -oc:\output.csv -h-1 -s","
答案 1 :(得分:0)
抛弃DataTable并使用DataReader。按顺序读取所需的记录并随时构建CSV文件。
答案 2 :(得分:0)
正如其他人所建议的那样,根据您的要求,应避免使用重量级DataTable。因此,使用其提供商的数据读取器从源流式传输数据将为您提供最佳性能,同时保持纤薄的内存配置文件。
我做了一些快速搜索,但无法提出任何csv库实现(有很多,远非详尽的搜索),吹嘘使用DataReader进行简单的即插即用。但是,使用CSV库(我之前已成功使用FileHelpers和kbcsv)来处理文件写入,从查询中加载数据读取器,在开始循环之前告诉csv编写器列名称然后使用它是非常简单的让作者处理将结果流式传输到磁盘。
在此过程中可能会增加一些内存,因为文件写入流可能会有一个不错的缓冲区,但它会比以数据中心方式更少的内存消耗方式。我以这种方式使用具有大结果集的datareader真正看到的唯一缺点是长时间运行的查询可能来自ADO.NET数据提供者,但这完全是提供者特定的(但是一个常见的问题)您可以在沿着这条路线前看看数据库方面是否存在问题。
希望有所帮助。