0

可能重复:
如何在 C# 中有效地从 SQL 数据读取器写入文件?

我目前正在尝试创建一个使用只读访问权限的 Web 应用程序,以允许用户从我们的数据库中下载大文件。有问题的表中有 400,000 条记录,导出时会生成一个 50 MB 的 .csv 文件。

在 SQL 服务器上运行语句“SELECT * FROM [table]”大约需要 7 秒,从我的 Web 应用程序(托管在不同的服务器上)大约需要 33 秒。这是将所有数据读入 System.Data.SqlClient.SqlDataReader 对象。

我的问题是我无法将 SqlDataReader 转换为 .csv 文件。将 SqlDataReader 的每一行都转换成字符串,然后逐行输出到文件中需要将近 2 个小时,这是不可接受的。下面是我用来在 Web 应用程序的服务器上创建文件的代码:

    while (rdr.Read())
    {
        string lineout = "";
        for (int index = 0; index < rdr.FieldCount; index++)
            lineout += rdr[index].ToString().Replace(',', ' ') + ',';
        write(lineout, filename); //uses StreamWriter.WriteLine()
    }

一定有更好的方法。我环顾四周,看到了很多建议,基本上建议执行上述操作来创建文件。这适用于较小的桌子,但不适用于我们每天使用的两张非常大的桌子。谁能给我推动正确的方向?

4

1 回答 1

5

您可以尝试lineout使用 aStringBuilder而不是手动连接字符串来构建您的:

//you can test whether it makes any difference in performance declaring a single
//StringBuilder and clearing, or creating a new one per loop
var sb = new StringBuilder();

while (rdr.Read())
{
    for (int index = 0; index < rdr.FieldCount; index++)
        sb.Append(rdr[index].ToString().Replace(',', ' ').Append(',');

    write(sb.ToString(), filename); //uses StreamWriter.WriteLine()
    sb.Clear();
}

或者尝试直接写入文件并避免首先在内存中生成每一行:

//assume a StreamWriter instance has been created called sw...
while (rdr.Read())
{
    for (int index = 0; index < rdr.FieldCount; index++)
    {
        sw.Write(rdr[index].ToString().Replace(',', ' ');
        sw.WriteLine(",");
    }
}

//flush and close stream
于 2013-02-04T21:29:10.777 回答