2017-03-28 4 views
-1

Ich muss Excel-Datei mit 3000 Zeilen in MS SQL Server-Datenbank importieren, ich benutze C# mit Entity-Framework, die Sache dauert Operation dauert etwa 15-20 Minuten. Mache ich etwas falsch oder ist das normal?Importieren von Excel-Datei in SQL mit C# Entity FrameWork

ist hier foreach-Schleife von meinem Code, wo Pfade Pfaddatei zu übertreffen ist:

  foreach (var item in paths) 
      { 
       Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); 
       Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(item.Value); 
       Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1]; 
       Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange; 
       try 
       { 

        int rowCount = xlRange.Rows.Count; 
        int colCount = xlRange.Columns.Count; 

        string GenDateString = xlRange.Cells[3, 6].Value2.ToString(); 
        string GenDate = GenDateString.Substring(0, 10); 
        string Client = xlRange.Cells[3, 1].Value2.ToString(); 
        string User = xlRange.Cells[3, 2].Value2.ToString(); 
        string error; 
        if (IsCorrectDate(item.Key, xlRange)) 
        { 
         CultureInfo provider = CultureInfo.InvariantCulture; 
         Import import = new Import() 
         { 
          Month = month, 
          year = year, 
          EndDate = item.Key[1], 
          GenerateDate = DateTime.ParseExact(GenDate, "dd.MM.yyyy", provider), 
          StartDate = item.Key[0], 
          FileName = item.Value.ToString() 
         }; 
         if (db.Imports.Any(i => i.StartDate == import.StartDate || i.EndDate == import.EndDate)) 
         { 
          try 
          { 
           progressbar.ReleaseBar(); 
          } 
          catch (Exception) 
          { 
          } 
          SAPbouiCOM.Framework.Application.SBO_Application.SetStatusBarMessage("ასეთი ფაილი უკვე შეიმპორტებულია", SAPbouiCOM.BoMessageTime.bmt_Short, true); 
          //cleanup 
          GC.Collect(); 
          GC.WaitForPendingFinalizers(); 

          //rule of thumb for releasing com objects: 
          // never use two dots, all COM objects must be referenced and released individually 
          // ex: [somthing].[something].[something] is bad 

          //release com objects to fully kill excel process from running in the background 
          Marshal.ReleaseComObject(xlRange); 
          Marshal.ReleaseComObject(xlWorksheet); 

          //close and release 
          xlWorkbook.Close(); 
          Marshal.ReleaseComObject(xlWorkbook); 

          //quit and release 
          xlApp.Quit(); 
          Marshal.ReleaseComObject(xlApp); 
          return; 
         } 
         for (int i = 8; i <= rowCount; i++) 
         { 
          Debug.WriteLine(i); 
          var bpCode = xlRange.Cells[i, 1].Value2.ToString(); 
          if (bpCode == "რეპორტის დასასრული") 
           break; 
          i++; 
          Mediator mediator = new Mediator() 
          { 
           BPCode = bpCode, 
           Import = import, 
          }; 

          for (int j = 0; j < clicks.Count(); j++) 
          { 
           progressbar.Up(); 
           rowsc--; 
           var clickName = xlRange.Cells[i + j, 1].Value2.ToString(); 
           Statistic SmeStatistic = new Statistic() 
           { 
            ClickNameID = clicks.FirstOrDefault(c => c.Name == clickName).ID, 
            ReqPerson = int.Parse(xlRange.Cells[i + j, 2].Value2.ToString()), 
            ReqBussiness = int.Parse(xlRange.Cells[i + j, 3].Value2.ToString()), 
            ResPerson = int.Parse(xlRange.Cells[i + j, 5].Value2.ToString()), 
            ResBussiness = int.Parse(xlRange.Cells[i + j, 6].Value2.ToString()), 
            Mediator = mediator, 
           }; 
           //var xxx = clicks.FirstOrDefault(c => c.Name == clickName).ID; 
           db.Statistics.Add(SmeStatistic); 

          } 
          i += clicks.Count() - 1; 
         } 
        } 
        else 
        { 
         //int iReturnValue = SAPbouiCOM.Framework.Application.SBO_Application.MessageBox(item.Value + " ფაილის თარიღი არასწორია.", 1, "&Ok"); 
         try 
         { 
          progressbar.ReleaseBar(); 
         } 
         catch (Exception) 
         { 
         } 
         SAPbouiCOM.Framework.Application.SBO_Application.SetStatusBarMessage("ფაილის თარიღები არ ემთხვევა არჩეულ პერიოდს", SAPbouiCOM.BoMessageTime.bmt_Short, true); 
         //cleanup 
         GC.Collect(); 
         GC.WaitForPendingFinalizers(); 

         //rule of thumb for releasing com objects: 
         // never use two dots, all COM objects must be referenced and released individually 
         // ex: [somthing].[something].[something] is bad 

         //release com objects to fully kill excel process from running in the background 
         Marshal.ReleaseComObject(xlRange); 
         Marshal.ReleaseComObject(xlWorksheet); 

         //close and release 
         xlWorkbook.Close(); 
         Marshal.ReleaseComObject(xlWorkbook); 

         //quit and release 
         xlApp.Quit(); 
         Marshal.ReleaseComObject(xlApp); 
         return; 
        } 
       } 
       catch (Exception ex) 
       { 
        SAPbouiCOM.Framework.Application.SBO_Application.MessageBox(ex.Message); 
       } 
       finally 
       { 
        //cleanup 
        GC.Collect(); 
        GC.WaitForPendingFinalizers(); 

        //rule of thumb for releasing com objects: 
        // never use two dots, all COM objects must be referenced and released individually 
        // ex: [somthing].[something].[something] is bad 

        //release com objects to fully kill excel process from running in the background 
        Marshal.ReleaseComObject(xlRange); 
        Marshal.ReleaseComObject(xlWorksheet); 

        //close and release // 

        //xlWorkbook.Close(); 
        Marshal.ReleaseComObject(xlWorkbook); 


        //quit and release 
        //xlApp.Quit(); 
        //Marshal.ReleaseComObject(xlApp); 
       } 

      } 
+1

ORMs sind * nicht * für ETL-Jobs geeignet. Sie bieten in diesem Szenario überhaupt nichts - es sind keine Geschäftseinheiten oder Regeln beteiligt, sondern nur Datenströme und Transformationen. Verwenden Sie SqlBulkCopy, um Daten so schnell wie möglich in die Datenbank zu importieren. Excel-Interop ist auch sehr langsam. Verwenden Sie entweder den Jet OLEDB-Provider, um die Excel-Datei zu lesen, oder eine Bibliothek wie EPPlus, die Excel-Dateien direkt lesen kann. Der Jet-Treiber ist der schnellste aber –

+0

Danke Sir, Jet-Treiber hat mir wirklich geholfen, jetzt dauert es nur 1 Minute, um jede Datei zu importieren! –

+0

@Mark Fitzgerald Ich benutzte OLEDB mit Vergnügen, bis mein Client diesen Fehler "System-Ressource überschritten." Excel-Datei ist etwa 100kb und 2.2k Zeilen. Mit den gleichen Dateien funktioniert es großartig auf meinem PC oder einem anderen PC in meinem Büro, kannst du mir irgendetwas raten? –

Antwort

1

Sie ein neuer Excel-Anwendungsobjekt (xlApp) jedes Mal, wenn die Schleife Kreise zu schaffen - dies langsam. Versuchen Sie, es vor der Schleife zu erstellen, damit Sie es wiederverwenden können.

Es kann andere Dinge geben, die Sie tun können, um es zu beschleunigen, aber ich bin geneigt, dem Kommentar von Panagiotis zuzustimmen - benutzen Sie Interop hier nicht. Ich bin auch in dieses Kaninchenloch gegangen und es ist sehr viel komplizierter und langsamer als mit JET OLEDB.

Dies ist eine grobe Anleitung, wie Sie Jet stattdessen verwenden könnte - ich füllen nur eine Datentabelle irgendwo in der Schleife zu verwenden:

using System.Data.OleDb; 

foreach (var item in paths) 
{ 
    string excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + item + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\""; 

    using (OleDbConnection excelConnection = new OleDbConnection(excelConnectionString)) 
    { 
     excelConnection.Open(); 

     DataTable dt = new DataTable(); //excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" }); 
     string query = sheetname.Contains(" ") ? string.Format("Select * from ['{0}$']", sheetname) : string.Format("Select * from [{0}$]", sheetname); 
     using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, excelConnection)) 
     { 
      dataAdapter.Fill(dt); 
     } 

     //do something with the data here 

     excelConnection.Close(); 
    } 
} 
+1

Vielen Dank! Ich bin auf JET OLEDB umgestiegen und es hat die Leistung wirklich gesteigert. –