2016-05-16 72 views
0

我有非常大的XLSX文件(6張,每張100萬行,每列19列)。這個想法是讀取所有工作表中的所有行,並使用實體框架填充數據庫。C#讀取大型EXCEL XLSX和寫入數據到SQL Server EXPRESS數據庫與實體框架性能問題

我已經嘗試ms打開xml sdk,但它真的很慢。只需遍歷所有行和單元格(以sax方式),我可能會運行我的程序一個月或更多。

我也試過這個庫https://github.com/ExcelDataReader/ExcelDataReader。最初,使用這個庫的讀取開始速度要快得多(在db插入的情況下,2秒鐘內大約有100行),但是它比較慢(50000行,1分鐘以上)。也許速度下降會導致實體框架 - 我沒有測試(我只測試沒有db訪問的前1000行),但即使是這樣,沒有任何東西的閱讀也太慢了。

有沒有人有任何想法我怎麼能加快閱讀xlsx?另外,我是否應放棄實體框架並自行插入?

目前我的代碼看起來像(有東西像columnMapper.Populate(tmpColumns, columns);columnMapper.getCOlumnId因爲不同的表有不同順序列,甚至不同的列數)

using (FileStream stream = File.Open(inputFilePath, FileMode.Open, FileAccess.Read)) 
{ 
    IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); 
    DataSet result = excelReader.AsDataSet(); 

    int tableNo = 0; 
    string[] tmpColumns = new string[20]; 
    Console.WriteLine("Start processing..."); 
    foreach (DataTable table in result.Tables) 
    { 
     // skip bad table 
     if (++tableNo > 5) 
     { 
      continue; 
     } 

     for (int i = 0; i < tmpColumns.Length; ++i) 
     { 
      tmpColumns[i] = string.Empty; 
     } 

     int columns = 0; 
     var rowEnumerator = table.Rows.GetEnumerator(); 
     rowEnumerator.MoveNext(); 
     foreach (string item in ((DataRow)rowEnumerator.Current).ItemArray) 
     { 
      tmpColumns[columns++] = item; 
     } 

     columnMapper.Populate(tmpColumns, columns); 

     int rowNumber = 0; 
     while (rowEnumerator.MoveNext()) 
     { 
      var row = (DataRow)rowEnumerator.Current; 
      int col = 0; 
      foreach (object item in row.ItemArray) 
      { 
       tmpColumns[columnMapper.GetColumnId(col++)] = item.ToString(); 
      } 


      var newBoxData = new BoxData() 
      { 
... 
       Year = tmpColumns[4], 
       RetentionPeriod = tmpColumns[6], 
       ContractNumber = tmpColumns[7], 
       Mbr = tmpColumns[8], 
       CardId = tmpColumns[10], 
       Package = tmpColumns[12], 
       UnitType = tmpColumns[13], 

       MFCBox = tmpColumns[14], 
       DescriptionNameAndSurname = tmpColumns[15], 
       DateFromTo = tmpColumns[16], 
       OrderNumberRange = tmpColumns[17], 
       PartnerCode = tmpColumns[18], 
      }; 

      db.BoxesDatas.Add(newBoxData); 

      if (++rowNumber % SaveAfterCount == 0) 
      { 
       db.SaveChanges(); 
       Console.WriteLine(rowNumber); 
      } 
     } 
    } 

    db.SaveChanges(); 

編輯:解決方法是刪除實體FW並用普通的sql命令插入數據。所以,在離開ms庫(實體fw,打開xml sdk)並將它們替換爲ExcelDataReader和純sql後,所有工作都會更快。 〜200萬行提取並在DB插入少於20分鐘

+0

可以在數據加載後向表中添加索引嗎? – BugFinder

+0

你可以從實體框架更改爲純Ado.net嗎?您可以使用批量插入。方式更快... –

+0

是的,我現在已經測試過了。 350000行5分鐘沒有db.SaveChanges每100行 – Igor

回答

1

解決XL演出結束後你還EF存在性能問題。
第一步是創建一個新的DbContext(即在SaveChanges之後)。
第二步是使用不同的ORM。

+1

第三步是使用普通的sql命令:)離開ms庫(實質fw,打開xml sdk),一切工作真的很快:)謝謝你的建議 – Igor

相關問題