2017-05-25 16 views
2

C#を使用してデータをエクスポートして.csvファイルにインポートするプロジェクトを行っています。私はデータをエクスポートすることに固執するので、私は以下のコードを書いたが、それ以上の柔軟性はない。私はそれを短時間で輸出したい。以下のコードはもっと時間がかかります。私はクエリを使用してSQL Serverから大量のデータを取得します。SQL ServerからCSVへ高速データをエクスポートする方法

public static void ExportPlantData(string channelId) 
{ 
    string query = string.Empty; 

    DataService dataService = new DataService(); 
    DbCommand dataCmd = null; 
    DataTable contentToExport = new DataTable(); 

    try 
    { 
     query = "SELECT * from tablename"; 

     dataCmd = dataService.Database.GetSqlStringCommand(query); 
     contentToExport = dataService.ExecuteDataTable(dataCmd); 
     ExportToCSV(contentToExport); 
    }  
} 

Iは、テーブルから大量のデータをフェッチしました。後、私は.csvにそのデータをエクスポートするつもりですが、それは、このコードをエクスポートするのに長い時間がかかる:あなたはメモリの再割り当ての原因となる文字列を構築し続けるので、それは遅いです

public static void ExportToCSV(DataTable contentToexport) 
{ 
    string csvData = string.Empty; 
    string headers = string.Empty; 

    foreach (DataRow row in contentToexport.Rows) 
    { 
     headers = string.Empty; 

     foreach (DataColumn column in contentToexport.Columns) 
     { 
      csvData += row[column].ToString() + ","; 
      headers += column.ColumnName + ","; 
     } 

     csvData += "\r\n"; 
     headers += "\r\n"; 
    } 

    string contentToExport = headers + csvData; 
    string attachment = "attachment; filename=export.csv"; 

    HttpContext.Current.Response.Clear(); 
    HttpContext.Current.Response.ClearHeaders(); 
    HttpContext.Current.Response.ClearContent(); 
    HttpContext.Current.Response.AddHeader("content-disposition", attachment); 
    HttpContext.Current.Response.ContentType = "application/csv"; 
    HttpContext.Current.Response.AddHeader("Pragma", "public"); 
    HttpContext.Current.Response.Write(contentToExport); 

    System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest(); 
} 
+0

ビジネスルールがなく、同様にselect文で取得したものがcsvにエクスポートされたければ、すべての列値をカンマ区切りの値としてすべての行に対して選択する必要があります。 1列に複数の行が表示されます。次に、アプリケーションの行だけを反復処理する必要があります。 –

+1

StringBuilderオブジェクトを使用する必要があります。 –

+1

なぜ**ホイールをもう一度作り直すのですか?**多くの**既製の** CSVエクスポートライブラリを使用してください。 [Josh CloseによるCSVHelper](https://joshclose.github.io/CsvHelper/) –

答えて

1

理由があります。代わりにStringBuilderを使用してください。次に、一度ではなく、すべての行でヘッダーを作成し続けるバグがあります。

public static void ExportToCSV(DataTable contentToexport) 
     { 
      var csvData = new StringBuilder(); 

      foreach (DataColumn column in contentToexport.Columns) 
      { 
       if (csvData.Length > 0) csvData.Append(","); 
       csvData.Append(column.ColumnName); 
      } 
      csvData.Append(Environment.NewLine); 

      foreach (DataRow row in contentToexport.Rows) 
      { 
       var newLine = true; 
       foreach (DataColumn column in contentToexport.Columns) 
       { 
        if (!newLine) csvData.Append(","); 
        newLine = false; 
        var cellValue = row[column].ToString(); 
        var cellValueHasQuotes = cellValue.Contains("\""); 
        if (cellValueHasQuotes) 
        { 
         csvData.Append("\""); 
         cellValue = cellValue.Replace("\"", "\"\""); 
        } 
        csvData.Append(cellValue); 
        if (cellValueHasQuotes) 
        { 
         csvData.Append("\""); 
        } 
       } 

       csvData.Append(Environment.NewLine); 
      } 

      string contentToExport = csvData.ToString(); 
      string attachment = "attachment; filename=export.csv"; 

      HttpContext.Current.Response.Clear(); 
      HttpContext.Current.Response.ClearHeaders(); 
      HttpContext.Current.Response.ClearContent(); 
      HttpContext.Current.Response.AddHeader("content-disposition", attachment); 
      HttpContext.Current.Response.ContentType = "application/csv"; 
      HttpContext.Current.Response.AddHeader("Pragma", "public"); 
      HttpContext.Current.Response.Write(contentToExport); 
      System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest(); 
     } 

もう1つの可能性は、いくつかの変更を加えてレスポンスボディに直接書き込むことです。

1
は、変数あなたの文字列を変更し、それを作る気にいらない。これは、あなたがより速く、以前のバージョンよりも働いていたでしょう

public static void ExportToCSV(DataTable contentToexport) 
{ 
    StringBuilder csvData = new StringBuilder(); 
    StringBuilder headers = new StringBuilder(); 

    foreach (DataRow row in contentToexport.Rows) 
    { 
     headers = string.Empty; 
     foreach (DataColumn column in contentToexport.Columns) 
     { 
      csvData.Append(row[column].ToString() + ","); 
      headers.Append(column.ColumnName + ","); 
     } 

     csvData.Append("\r\n"); 
     headers.Append("\r\n"); 
    } 

    string contentToExport = headers.Append(csvData.ToString()).ToString(); 
    string attachment = "attachment; filename=export.csv"; 

    HttpContext.Current.Response.Clear(); 
    HttpContext.Current.Response.ClearHeaders(); 
    HttpContext.Current.Response.ClearContent(); 
    HttpContext.Current.Response.AddHeader("content-disposition", attachment); 
    HttpContext.Current.Response.ContentType = "application/csv"; 
    HttpContext.Current.Response.AddHeader("Pragma", "public"); 
    HttpContext.Current.Response.Write(contentToExport); 
    System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest(); 
} 

よう

関連する問題