如何在c#中有效地从SQL datareader写入文件?

Sam*_*Sam 8 c# sqldatareader writetofile

我在C#中有一个远程sql连接,需要执行查询并将其结果保存到用户的本地硬盘.这个东西可以返回相当大量的数据,因此需要考虑一种有效的存储方式.我之前已经读过,先将整个结果放入记忆中,然后写出来并不是一个好主意,所以如果有人可以提供帮助,那就太好了!

我目前正在将sql结果数据存储到DataTable中,虽然我认为它可以更好地做一些事情while(myReader.Read(){...} 下面是得到结果的代码:

          DataTable t = new DataTable();
            string myQuery = QueryLoader.ReadQueryFromFileWithBdateEdate(@"Resources\qrs\qryssysblo.q", newdate, newdate);
            using (SqlDataAdapter a = new SqlDataAdapter(myQuery, sqlconn.myConnection))
            {
                a.Fill(t);
            }

            var result = string.Empty;
    for(int i = 0; i < t.Rows.Count; i++)
    {
        for (int j = 0; j < t.Columns.Count; j++)
        {
            result += t.Rows[i][j] + ",";
        }


        result += "\r\n";
    }
Run Code Online (Sandbox Code Playgroud)

所以现在我有了这个巨大的结果字符串.我有数据表.必须有一个更好的方法吗?

谢谢.

And*_*bel 19

你自己走在正确的轨道上.使用循环while(myReader.Read(){...}并将每个记录写入循环内的文本文件..NET框架和操作系统将以有效的方式将缓冲区刷新到磁盘.

using(SqlConnection conn = new SqlConnection(connectionString))
using(SqlCommand cmd = conn.CreateCommand())
{
  conn.Open();
  cmd.CommandText = QueryLoader.ReadQueryFromFileWithBdateEdate(
    @"Resources\qrs\qryssysblo.q", newdate, newdate);

  using(SqlDataReader reader = cmd.ExecuteReader())
  using(StreamWriter writer = new StreamWriter("c:\temp\file.txt"))
  {
    while(reader.Read())
    {
      // Using Name and Phone as example columns.
      writer.WriteLine("Name: {0}, Phone : {1}", 
        reader["Name"], reader["Phone"]);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*ick 7

我想出了这个,它是一个比其他答案更好的 CSV 编写器:

public static class DataReaderExtension
{
    public static void ToCsv(this IDataReader dataReader, string fileName, bool includeHeaderAsFirstRow)
    {

        const string Separator = ",";

        StreamWriter streamWriter = new StreamWriter(fileName);

        StringBuilder sb = null;

        if (includeHeaderAsFirstRow)
        {
            sb = new StringBuilder();
            for (int index = 0; index < dataReader.FieldCount; index++)
            {
                if (dataReader.GetName(index) != null)
                    sb.Append(dataReader.GetName(index));

                if (index < dataReader.FieldCount - 1)
                    sb.Append(Separator);
            }
            streamWriter.WriteLine(sb.ToString());
        }

        while (dataReader.Read())
        {
            sb = new StringBuilder();
            for (int index = 0; index < dataReader.FieldCount; index++)
            {
                if (!dataReader.IsDBNull(index))
                {
                    string value = dataReader.GetValue(index).ToString();
                    if (dataReader.GetFieldType(index) == typeof(String))
                    {
                        if (value.IndexOf("\"") >= 0)
                            value = value.Replace("\"", "\"\"");

                        if (value.IndexOf(Separator) >= 0)
                            value = "\"" + value + "\"";
                    }
                    sb.Append(value);
                }

                if (index < dataReader.FieldCount - 1)
                    sb.Append(Separator);
            }

            if (!dataReader.IsDBNull(dataReader.FieldCount - 1))
                sb.Append(dataReader.GetValue(dataReader.FieldCount - 1).ToString().Replace(Separator, " "));

            streamWriter.WriteLine(sb.ToString());
        }
        dataReader.Close();
        streamWriter.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:mydataReader.ToCsv("myfile.csv", true)