我有一个最初有大约600行的Excel文件,我能够将excel文件转换为数据表,所有内容都正确地插入到sql表中。
Excel文件现在有3,600行,并且有一些类型的问题没有引发错误,但是在5分钟左右之后,所有行仍未插入到sql表中。
现在,当将Excel文件转换为内存数据表时,这种情况发生得非常快,但是当循环数据表并插入到sql表中时,我丢失数据并且速度非常慢,但是我是这样做的。我没有收到任何错误。
首先,在每个插页上,我必须与数据库建立新连接并插入记录,我已经知道这非常非常错误,我希望得到一些指导这个sql专业人员之一。
处理具有3,600条记录/行的内存数据表的正确方法是什么,而没有创建3,600个新连接?
- 以下是处理excel文件的代码,这很快就会发生.--
public static async Task<DataTable> ProcessExcelToDataTableAsync(string pathAndNewFileName, string hasHeader/*Yes or No*/)
{
return await Task.Run(() =>
{
string conStr = "", SheetName = "";
switch (Path.GetExtension(pathAndNewFileName))
{
case ".xls": //Excel 97-03
conStr = ConfigurationManager.ConnectionStrings["Excel03ConString"].ConnectionString;
break;
case ".xlsx":
conStr = ConfigurationManager.ConnectionStrings["Excel07ConString"].ConnectionString;
break;
}
conStr = String.Format(conStr, pathAndNewFileName, hasHeader);
OleDbConnection connExcel = new OleDbConnection(conStr);
OleDbCommand cmdExcel = new OleDbCommand();
OleDbDataAdapter oda = new OleDbDataAdapter();
DataTable dt = new DataTable();
cmdExcel.Connection = connExcel;
//Get the name of First Sheet
connExcel.Open();
DataTable dtExcelSchema;
dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
connExcel.Close();
//Read Data from First Sheet
connExcel.Open();
cmdExcel.CommandText = "SELECT * From [" + SheetName + "]";
oda.SelectCommand = cmdExcel;
oda.Fill(dt);
connExcel.Close();
cmdExcel.Dispose();
oda.Dispose();
if (File.Exists(pathAndNewFileName))
{
File.Delete(pathAndNewFileName);
}
return dt;
});
}
- 这是处理内存数据表并将每个新记录插入sql表的代码,这是事情停止工作,没有可见错误,但只是不返回或工作 -
* *我需要一种更好的方法来优化此功能,其中记录被插入到sql表中。
static async Task<ProcessDataTablePartsResult> ProcessDataTablePartsAsync(int genericCatalogID, DataTable initialExcelData)
{
//@GenericCatalogID INT,
//@Number VARCHAR(50),
//@Name VARCHAR(200),
//@Length DECIMAL(8,4),
//@Width DECIMAL(8,4),
//@Height DECIMAL(8,4),
//@ProfileID TINYINT,
//@PackageQty DECIMAL(9,4),
//@CategoryID INT,
//@UnitMeasure VARCHAR(10),
//@Cost MONEY,
//@PartID INT OUT
return await Task.Run(() =>
{
DataTable badDataTable = null,
goodDataTable = initialExcelData.Clone();
goodDataTable.Clear();
int newPartID = 0,
currIx = 0,
numGoodRows = initialExcelData.Rows.Count,
numBadRows = 0;
List<int> badIndexes = new List<int>();
List<int> goodIndexes = new List<int>();
List<Profile> profiles = GenericCatalogManagerBL.GetProfiles(_genericCNN);
List<Category> categories = GenericCatalogManagerBL.GetAllCategoryNameID(_genericCNN);
Func<string, byte> getProfileID = delegate(string x)
{
return profiles.Where(p => p.TheProfile.ToLower().Replace(" ", "") == x.ToLower().Replace(" ", "")).FirstOrDefault().ID;
};
Func<string, int> getCategoryID = delegate(string x)
{
return categories.Where(c => c.Name.ToLower().Replace(" ", "") == x.ToLower().Replace(" ", "")).FirstOrDefault().ID;
};
foreach (DataRow r in initialExcelData.Rows)
{
try
{
IPart p = new Part
{
GenericCatalogID = genericCatalogID,
Number = r["Number"].ToString(),
Name = r["Name"].ToString(),
Length = decimal.Parse(r["Length"].ToString()),
Width = decimal.Parse(r["Width"].ToString()),
Height = decimal.Parse(r["Height"].ToString()),
ProfileID = getProfileID(r["Profile"].ToString()),
CategoryID = getCategoryID(r["Category"].ToString()),
PackageQty = int.Parse(r["PackageQty"].ToString()),
UnitMeasure = r["UnitMeasure"].ToString(),
Cost = decimal.Parse(r["Cost"].ToString())
};
GenericCatalogManagerBL.InsertPart(_genericCNN, p, out newPartID);
goodIndexes.Add(currIx);
}
catch (Exception)
{
numBadRows++;
numGoodRows--;
badIndexes.Add(currIx);
}
currIx++;
}
for (int i = 0; i < goodIndexes.Count; i++)
{
goodDataTable.ImportRow(initialExcelData.Rows[goodIndexes[i]]);
initialExcelData.Rows[goodIndexes[i]].Delete();
}
initialExcelData.AcceptChanges();
goodDataTable.AcceptChanges();
if (initialExcelData.Rows.Count > 0)
{
badDataTable = initialExcelData;
}
return new ProcessDataTablePartsResult(numGoodRows, numBadRows, badDataTable, goodDataTable);
});
}
**--Here is the entire flow of the function--**
public static async Task<GenericPartsReport> ProcessGenericPartsAsync(int genericCatalogID, MembershipUser user, HttpRequest request, bool emailReport, bool hasHeaders)
{
byte[] fbytes = new byte[request.ContentLength];
request.InputStream.Read(fbytes, 0, fbytes.Length);
string pathAndNewFileName = Path.GetRandomFileName() + Path.GetExtension(request.Headers["X-FILE-NAME"]),
badReportTableString = "",
goodReportTableString = "";
GenericPartsReport report = new GenericPartsReport();
//get the users temp folder
pathAndNewFileName = UtilCommon.SiteHelper.GetUserTempFolder(user, request) + pathAndNewFileName;
File.WriteAllBytes(pathAndNewFileName, fbytes);
//process the excel file first
DataTable excelDataTable = await ProcessExcelToDataTableAsync(pathAndNewFileName, hasHeaders ? "Yes" : "No");
ProcessDataTablePartsResult processedResult = await ProcessDataTablePartsAsync(genericCatalogID, excelDataTable);
if (processedResult.BadDataTable != null)
{
if (processedResult.BadDataTable.Rows.Count > 0)
{
badReportTableString = await BuildTableReportAsync(processedResult.BadDataTable, "AlumCloud Parts Not Added Report");
processedResult.BadDataTable.Dispose();
}
}
if (processedResult.GoodDataTable != null)
{
if (processedResult.GoodDataTable.Rows.Count > 0)
{
goodReportTableString = await BuildTableReportAsync(processedResult.GoodDataTable, "AlumCloud Parts Added Report");
processedResult.GoodDataTable.Dispose();
}
}
report.Report = "A total number of (" + processedResult.NumberOfGoodRows + ") records was added to your generic catalog.<br/><br/>A total number of (" + processedResult.NumberOfBadRows + ") records were excluded from being added to your generic catalog.";
if (processedResult.NumberOfBadRows > 0)
{
report.Report += "<br/><br/>You can review an excel file that meets the standards here: <a href='" + _exampleExcelFile + "'>How to format a part excel file</a>.";
report.HasBadRows = true;
}
if (processedResult.NumberOfGoodRows > 0)
{
report.Report += "<br/><br/><b>Below is all of the parts that were added to your generic catalog<b/><br/><br/>" + goodReportTableString;
}
if (processedResult.NumberOfBadRows > 0)
{
report.Report += "<br/><br/><b>Below is all of the parts that were not added to your generic catalog</b><br/><br/>" + badReportTableString;
}
if (emailReport)
{
AFCCIncCommonUtil.EmailUtil.SendMailToThreadPool(user.Email, _supportEmail, report.Report, "AlumCloud Generic Catalog Parts Report", true);
}
excelDataTable.Dispose();
return report;
}
- 这是一个永不返回或处于某种状态的功能 -
ProcessDataTablePartsResult processedResult = await ProcessDataTablePartsAsync(genericCatalogID, excelDataTable);