2017-03-28 3 views
-1

J'ai besoin d'importer un fichier Excel avec 3000 lignes dans la base de données MS SQL Server, je suis en utilisant C# avec le cadre de l'entité, chose est opération prend trop de temps environ 15 à 20 minutes. Est-ce que je fais quelque chose de mal ou est-ce normal?Importation de fichiers Excel à SQL avec C# Entité FrameWork

Voici boucle foreach de mon code où les chemins est le chemin d'un fichier Excel:

  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

ORM sont * pas * adapté aux emplois ETL. Ils n'offrent rien du tout dans ce scénario - il n'y a pas d'entités commerciales ou de règles impliquées, seulement des flux de données et des transformations. Utilisez SqlBulkCopy pour importer les données dans la base de données aussi vite que possible. Utiliser Excel interop est extrêmement lent aussi. Utilisez soit le fournisseur Jet OLEDB pour lire le fichier Excel ou une bibliothèque comme EPPlus qui peut lire directement les fichiers Excel. Le pilote de Jet est le plus rapide que –

+0

Merci Monsieur, pilote Jet m'a vraiment aidé, maintenant il ne prend que 1 minute pour importer chaque fichier! –

+0

Fitzgerald Je @ Mark utilisait OLEDB avec plaisir jusqu'à ce que mon client a cette erreur « ressource système dépassé. » fichier Excel est d'environ 100kb et 2.2k lignes. Avec les mêmes fichiers cela fonctionne très bien sur mon pc ou tout autre pc dans mon bureau, pouvez-vous me conseiller quelque chose? –

Répondre

1

Vous créez un nouvel objet d'application Excel (xlApp) à chaque fois que les cercles de boucle - ce sera lent. Essayez de le créer avant la boucle afin de pouvoir le réutiliser.

Il peut y avoir d'autres choses que vous pouvez faire pour accélérer, mais je suis plutôt d'accord avec le commentaire de Panagiotis - ne pas utiliser Interop ici. Je suis descendu ce trou de lapin aussi, et il est extrêmement plus compliqué et plus lent que JET OLEDB.

Voici une idée approximative de la façon dont vous pourriez utiliser un jet au lieu - je vous suffit de remplir un tableau de données à utiliser quelque part dans la boucle:

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

Merci beaucoup! Je suis passé à JET OLEDB et cela a vraiment boosté les performances. –