1

我有一个DataTable可以放置数十万条记录的文件。这是一个巨大的内存开销,所以我添加了一个功能,用户只能在我的应用程序中可视化前 200 条记录,并且可以将其余结果导出到 CSV 文件。

但是,为了导出到 CSV 文件,我使用的方法是将 a 的内容转换为DataTableCSV 文件。由于我可以在 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());
4

3 回答 3

0

我会去老学校并使用sqlcmd。就像是:

sqlcmd -q "select field1,field2,field3 from mytable" -oc:\output.csv -h-1 -s","

http://msdn.microsoft.com/en-us/library/ms162773.aspx

于 2013-02-22T00:55:28.530 回答
0

放弃 DataTable 并使用 DataReader。依次读取您需要的记录并随时构建 CSV 文件。

于 2013-02-22T00:57:18.653 回答
0

正如其他人所建议的那样,鉴于您的要求,应避免在此处使用重量级 DataTable。因此,使用其提供者的数据读取器从源中流式传输数据将为您提供最佳性能,同时保持纤薄的内存配置文件。

我进行了一些快速搜索,但无法提出任何 csv 库实现(有很多,远非详尽的搜索)吹捧使用 DataReader 轻松即插即用。然而,使用 CSV 库(我之前成功使用过 FileHelpers 和 kbcsv)来处理文件写入、从查询中加载数据读取器、在开始循环之前告诉 csv 写入器列名然后只需让作者处理将结果流式传输到磁盘即可。

在此期间您可能会增加一些内存,因为文件写入流可能会有一个不错的缓冲区,但与以数据表为中心的方法相比,它内存消耗要少得多。以这种方式使用具有大型结果集的数据读取器,我真正看到的唯一缺点是长时间运行的查询可能会从 ADO.NET 数据提供程序中消耗,但这完全是提供程序特定的(但一个常见问题)沿着这条路线走下去,您可以查看数据库方面是否有问题。

希望有帮助。

于 2013-02-22T12:38:11.007 回答