C# 以更省时的方式将数据从excel导入数据库

C# 以更省时的方式将数据从excel导入数据库,c#,asp.net,.net,C#,Asp.net,.net,我有一个excel文件,有7-8列和800-1200行,需要验证并插入数据库,我所做的是将excel加载到OleDB数据读取器并沿行读取。数据经过检查和验证并加载到datatable,然后使用SqlBulkCopy将其写入服务器 string ConnectionStr = string.Empty; if (extension.ToUpper() == ".XLS") { ConnectionStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data So

我有一个excel文件,有7-8列和800-1200行,需要验证并插入数据库,我所做的是将excel加载到OleDB数据读取器并沿行读取。数据经过检查和验证并加载到datatable,然后使用
SqlBulkCopy
将其写入服务器

string ConnectionStr = string.Empty;

if (extension.ToUpper() == ".XLS")
{
   ConnectionStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("~/Cookies/BatchFile/" + FileName) + ";Extended Properties=Excel 8.0";
}
else
{
   ConnectionStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Server.MapPath("~/Cookies/BatchFile/" + FileName) + ";Extended Properties=Excel 12.0";
}

DataTable Err = new DataTable();
dter.Columns.Add("MainCode", typeof(string));
dter.Columns.Add("Remarks", typeof(string));

DataTable DtASBAMaster = new DataTable();
DtASBAMaster.Columns.Add("ASBARef");
DtASBAMaster.Columns.Add("ClientCode");
DtASBAMaster.Columns.Add("BranchCode");
DtASBAMaster.Columns.Add("ShareHolderAc");
DtASBAMaster.Columns.Add("CyCode");
DtASBAMaster.Columns.Add("AcType");
DtASBAMaster.Columns.Add("DMATId");
DtASBAMaster.Columns.Add("ClientId");
DtASBAMaster.Columns.Add("BOId");
DtASBAMaster.Columns.Add("BankCode");
DtASBAMaster.Columns.Add("OpenDate");
DtASBAMaster.Columns.Add("EnteredBy");
DtASBAMaster.Columns.Add("ApprovedBy");
DtASBAMaster.Columns.Add("Name");
DtASBAMaster.Columns.Add("ASBAStatus");

DataTable Dtimport = new DataTable();
Dtimport.Columns.Add("BatchNo");
Dtimport.Columns.Add("BranchCode");
Dtimport.Columns.Add("AcType");
Dtimport.Columns.Add("CyCode");
Dtimport.Columns.Add("MainCode");
Dtimport.Columns.Add("TranDate");
Dtimport.Columns.Add("NoOfShare");
Dtimport.Columns.Add("Name");
Dtimport.Columns.Add("BankCode");
Dtimport.Columns.Add("ThisBranch");
Dtimport.Columns.Add("RegNo");
Dtimport.Columns.Add("DMATId");
Dtimport.Columns.Add("ClientId");
Dtimport.Columns.Add("TakeCharge");

while (odr.Read())
{                       
   //Check values against next table to database -->Database trip 1
   SqlDataReader dr = DataAccess.ASBA.DA_Asba.GetMainCodeAsba(Session["ConnSTR"].ToString(), mainCode: MainCode);
   if (dr.Read())
   {
      //Perform Action if value are inseted in next table 
   }
   else
   {
      if (New == "T")
      {
         //Fetch Details from someother table in database to load in next table
         //add to datatable DtASBAMaster

        else {
                //Add to  datatable Err
                continue;
             }
      }

      //Calculation and stuffs 
      if (!GetBalance(MainCode, TotalAmount.ToString(), IsChargeASBA))
      {
         //Add to  datatable Err
      }
      else
      {
         if (!MainCodeProcessed.Add(MainCode))
         {
            dter.Rows.Add(MainCode, "Dublicate Maincode in the Batch");
            continue;
         }

         Dtimport.Rows.Add(BatchNo, BranchCode, AcType, CyCode, MainCode, SimpleHTTPModule.Today.ToString(), NoOfShare, Name, Session["BranchCodeSelected"].ToString(), Session["BranchCodeSelected"].ToString(), RegisterNo, Dmate, Clientid, IsChargeASBA);

    }

 }
 SqlTransaction myTrans = null;
 conn.Open();
 SqlCommand cmd = new SqlCommand();
 myTrans = conn.BeginTransaction();
 cmd.Connection = conn;
 cmd.Transaction = myTrans;
 try {
       successcount = Dtimport.Rows.Count;
       if (successcount > 0)
       {
          string Qrystring = @"INSERT INTO ASBABatApplyTable(BatchNo,BranchCode,BatchDetails,IsPrinted,IsApproved,EnteredBy,CompanyCode,IsuuedDate,NoOfTrans) values(@BatchNo,@BranchCode,@BatchDetails,@IsPrinted,@IsApproved,@EnteredBy,@CompanyCode,@IsuuedDate,@NoOfTrans)";
          ////Qrystring = Qrystring + " VALUES('" + BatchNo + "','" + BatchDetails + "','F','F','" + EnteredBy + "')";

          cmd.CommandText = Qrystring;
          cmd.Parameters.AddWithValue("@BatchNo", BatchNo);
          cmd.Parameters.AddWithValue("@BranchCode", Session["BranchCodeSelected"].ToString());//
          cmd.Parameters.AddWithValue("@BatchDetails", txtBatchDesc.Text);
          cmd.Parameters.AddWithValue("@IsPrinted", "F");
          cmd.Parameters.AddWithValue("@IsApproved", "F");
          cmd.Parameters.AddWithValue("@EnteredBy", EnteredBy);//
          cmd.Parameters.AddWithValue("@CompanyCode", txtCompanyCode.Text);
          cmd.Parameters.AddWithValue("@IsuuedDate", SimpleHTTPModule.Today.ToShortDateString());//
          cmd.Parameters.AddWithValue("@NoOfTrans", successcount);//
          cmd.ExecuteNonQuery();

          //bulk copy
          SqlBulkCopy tblcpyASBAMaster= new SqlBulkCopy(conn, SqlBulkCopyOptions.Default,myTrans);
          tblcpyASBAMaster.ColumnMappings.Add("ASBARef", "ASBARef");
          tblcpyASBAMaster.ColumnMappings.Add("ClientCode", "ClientCode");
          tblcpyASBAMaster.ColumnMappings.Add("BranchCode", "BranchCode");
          tblcpyASBAMaster.ColumnMappings.Add("ShareHolderAc", "ShareHolderAc");
          tblcpyASBAMaster.ColumnMappings.Add("CyCode", "CyCode");
          tblcpyASBAMaster.ColumnMappings.Add("AcType", "AcType");
          tblcpyASBAMaster.ColumnMappings.Add("DMATId", "DMATId");
          tblcpyASBAMaster.ColumnMappings.Add("ClientId", "ClientId");
          tblcpyASBAMaster.ColumnMappings.Add("BOId", "BOId");
          tblcpyASBAMaster.ColumnMappings.Add("BankCode", "BankCode");
          tblcpyASBAMaster.ColumnMappings.Add("OpenDate", "OpenDate");
          tblcpyASBAMaster.ColumnMappings.Add("EnteredBy", "EnteredBy");
          tblcpyASBAMaster.ColumnMappings.Add("ApprovedBy", "ApprovedBy");
          tblcpyASBAMaster.ColumnMappings.Add("Name", "Name");
          tblcpyASBAMaster.ColumnMappings.Add("ASBAStatus", "ASBAStatus");
          tblcpyASBAMaster.DestinationTableName = "ASBAMaster";
          tblcpyASBAMaster.WriteToServer(DtASBAMaster);

          SqlBulkCopy tblcpy = new SqlBulkCopy(conn,SqlBulkCopyOptions.Default, myTrans);
          tblcpy.ColumnMappings.Add("BatchNo", "BatchNo");
          tblcpy.ColumnMappings.Add("BranchCode", "BranchCode");
          tblcpy.ColumnMappings.Add("AcType", "AcType");
          tblcpy.ColumnMappings.Add("CyCode", "CyCode");
          tblcpy.ColumnMappings.Add("MainCode", "MainCode");
          tblcpy.ColumnMappings.Add("TranDate", "TranDate");
          tblcpy.ColumnMappings.Add("NoOfShare", "NoOfShare");
          tblcpy.ColumnMappings.Add("Name", "Name");
          tblcpy.ColumnMappings.Add("BankCode", "BankCode");
          tblcpy.ColumnMappings.Add("ThisBranch", "ThisBranch");
          tblcpy.ColumnMappings.Add("RegNo", "RegNo");
          tblcpy.ColumnMappings.Add("DMATId", "DMATId");
          tblcpy.ColumnMappings.Add("ClientId", "ClientId");
          tblcpy.ColumnMappings.Add("TakeCharge", "TakeCharge");
          tblcpy.DestinationTableName = "ASBABatApplyTran";
          tblcpy.WriteToServer(Dtimport);
          myTrans.Commit();
          Session["Imported"] = "IMPORTED :" + successcount + " Records";           
      }             
  }
目前,加载excel大约需要12-15分钟,如果数据库使用量很大,则需要更长的时间。如何对其进行优化以使其性能更好

p.S.可以自由地讨论编码约定,并使用替代/更好的方法进行实践,并就我的错误之处提出建议。多谢各位


编辑: 因此,在代码分析之后,我发现一条记录有4次数据库跳闸,删除了不必要的数据库跳闸,并将所有针对数据库值的验证移到sql函数中,以将数据库跳闸减少到1。此后,进口相对较快


非常感谢每一个人。:)

您应该分析您的代码,并确定发生减速的确切位置。看起来您正在为Excel文件中的每一行打开一个新的SqlDataReader(顺便说一句,您似乎没有关闭哪一行?)。这将非常缓慢。你能不能一次把所有的东西都读出来,然后记在记忆里(在字典里?)。但是很难说,因为从您的代码中完全不清楚SqlDataReader的用途。@JonathanWillcock,SqlDataReader将检查记录是否存在于另一个表中,并从该表中获取一些不是excel提供的数据。该另一个表包含多少行?如果不是太多,则可以更快地将其全部读入数据表中一次,然后将其保存在内存中,然后使用Select()对Excel文件中的每个步骤进行筛选。当前为13K,并且不断增加。我想,将所有数据加载到datatable中会比较慢。您应该分析代码并确定发生减速的确切位置。看起来好像您正在为Excel文件中的每一行打开一个新的SqlDataReader(顺便说一句,您似乎没有关闭哪一行?)。这将非常缓慢。你能不能一次把所有的东西都读出来,然后记在记忆里(在字典里?)。但是很难说,因为从您的代码中完全不清楚SqlDataReader的用途。@JonathanWillcock,SqlDataReader将检查记录是否存在于另一个表中,并从该表中获取一些不是excel提供的数据。该另一个表包含多少行?如果不是太多,则可以更快地将其全部读入数据表中一次,然后将其保存在内存中,然后使用Select()对Excel文件中的每个步骤进行筛选。当前为13K,并且不断增加。我想,将所有数据加载到datatable会更慢。