C# 以更省时的方式将数据从excel导入数据库
我有一个excel文件,有7-8列和800-1200行,需要验证并插入数据库,我所做的是将excel加载到OleDB数据读取器并沿行读取。数据经过检查和验证并加载到datatable,然后使用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
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会更慢。