Datatable Unpivot非常慢。任何替代品?

时间:2013-10-18 15:23:46

标签: c# sql-server excel entity-framework datatable

我有一个excel工作表,它有大约200行和大约200多列。我需要将此excel表格取消,并将其插入到sql server表中。我正在使用第三方excel api,它将excel工作表转换为ADO .Net Datatable。

原始数据表A. enter image description here

对于Unpivot opertation,我遍历原始的Datatable Rows和Columns,并将值分配给另一个已根据

定义的DataTable。

DataTable B UnPivoted enter image description here

在填充新的DataTable之后,我将在数据表上使用SQlBulkCopy()并将所有记录保存到SQLServer表。

我用于Un-Pivot操作的代码

//excelExport is the DataTable which stores the entire excel workSheet

DataTable newDatatable = new DataTable();   //For Un-Pivoting
newDatatable .Columns.Add(new DataColumn("EconomyID"));
newDatatable .Columns.Add(new DataColumn("SystemLanguage"));
newDatatable .Columns.Add(new DataColumn("VariableName"));
newDatatable .Columns.Add(new DataColumn("VariableValue"));
foreach (DataRow dr in excelExport.Rows)     //excelExport is the original datatable      
{
int colCount = 0;
       foreach (DataColumn dc in excelExport.Columns)
       {                    
          if (colCount >= 2)
          {
           DataRow dr2 = newDatatable.NewRow();                                           
           dr2["Economy"] = dr[1].ToString();
           dr2["SystemLanguageID"] = dr[2].ToString();
           dr2["VariableName"] = dc.ColumnName;
           dr2["VariableValue"] = dr[dc].ToString();
           newDatatable.Rows.Add(dr2);
          }
         colCount++;
       }
 } 

现在的问题是我的原始数据表A有200多列(和200行)。遍历每一行并将值分配给另一个newDatatable需要10秒。 所以整个操作需要200行* 10秒...基本上永远(取决于excel / datatable中的列);只是为了创建newDatatable。是否有更有效的方法来处理此非枢轴操作。我知道我们有SSIS包,它是为excel sqlserver导入操作而构建的,但我们的要求是客户端应该能够将excel上传到系统中,并且流程必须是实时的。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

对于200列,按列查找索引可能是罪魁祸首。您可以将查找更改为按列号而不是字符串名称:

   foreach (DataColumn dc in excelExport.Columns)
   {                    
      if (colCount >= 2)
      {
       DataRow dr2 = newDatatable.NewRow();                                           
       dr2[0] = dr[1].ToString();
       dr2[1] = dr[2].ToString();
       dr2[2] = dc.ColumnName;
       dr2[3] = dr[colCount].ToString();
       newDatatable.Rows.Add(dr2);
      }
     colCount++;
   }

虽然这只是猜测。我会投资一个很好的分析工具来测量过程缓慢并首先修复最慢的部分。

答案 1 :(得分:0)

构建新的DataTable比使用廉价的结构(如Tuple s)更贵。

var tuples = new List<Tuple<string, string, string, object>>();
foreach (DataRow dr in excelExport.Rows)
{
    int colCount = 0;
    foreach (DataColumn dc in excelExport.Columns)
    {                    
        if (colCount >= 2)
        {
            tuples.Add(Tuple.Create(dr[1],
                                    dr[2],
                                    dc.ColumnName,
                                    (object)dr[colCount])
                                   );
        }
        colCount++;
    }
}

您还可以跳过ToString()来电,因为Tuple.Create会使用类型推断来创建正确的元组。如果所有值恰好具有相同的数据类型,则最后一项可以具有显式类型(不是object),否则您需要(object)强制转换。