我创建了一个相当简单的程序来每年处理报告。直到最近它才起作用,但随着Access数据库的增加,该程序最终停止运行。当我在测试环境中收缩数据库时,它会继续按预期工作。
public List<WorkOrderModel> getAllWorkOrdersForYear(int year)
{
List<WorkOrderModel> workOrderList = new List<WorkOrderModel>();
conn = null;
//int connectionOpen = openConnection();
openConnection();
if (conn.State == ConnectionState.Open)
{
result = -1;
string sql;
string selectedDate = "04/30/" + (year);
string endDate = "05/01/" + (year + 1);
sql = "SELECT * FROM WorkOrder WHERE NOT Completed = 0 AND dateCompleted > #"
+ selectedDate + "# AND dateCompleted < #"
+ endDate + "# ORDER BY supervisor ASC;";
// load up and execute sql command
cmd = new OleDbCommand(sql, conn);
try
{
reader = cmd.ExecuteReader();
}
catch (Exception ex)
{
// error close the connection
conn.Close();
Console.Write("Error - " + ex.Message);
return workOrderList;
}
// successfully got data
if (reader.HasRows)
{
WorkOrderModel wom;
int num;
while (reader.Read())
{
//Note: try/catch's for fields with possible null/empty returns
num = 0;
// create a new workOrderModel object
wom = new WorkOrderModel();
// load up the object with values
wom.setWorkOrderNumber((int)reader.GetValue(num++));
wom.setUserID((int)reader.GetValue(num++));
wom.setFirstName(reader.GetString(num++));
wom.setLastName(reader.GetString(num++));
wom.setDateSubmitted(reader.GetDateTime(num++));
wom.setCustNum(reader.GetString(num++));
wom.setEquipment(reader.GetString(num++));
wom.setDescription(reader.GetString(num++));
// tech
try
{
wom.setTech(reader.GetString(num++));
}
catch { wom.setTech(""); }
wom.setLabour((double)reader.GetValue(num++));
wom.setShopFee((double)reader.GetValue(num++));
wom.setHardware((double)reader.GetValue(num++));
wom.setElectronicComponets((double)reader.GetValue(num++));
wom.setMaterials((double)reader.GetValue(num++));
wom.setLabourCost((double)reader.GetDecimal(num++));
wom.setSuppliesCost((double)reader.GetDecimal(num++));
wom.setTotalCost((double)reader.GetDecimal(num++));
// work performed
try
{
wom.setWorkPerformed(reader.GetString(num++));
}
catch { wom.setWorkPerformed(""); }
// date completed
try
{
wom.setDateCompleted(reader.GetDateTime(num++));
}
catch
{
DateTime tempDate = DateTime.MinValue;
wom.setDateCompleted(tempDate);
}
// completion flag
wom.setIsComplete(reader.GetBoolean(num++));
//phone
try
{
wom.setPhone(reader.GetString(num++));
}
catch { wom.setPhone(""); }
//email
try
{
wom.setEmail(reader.GetString(num++));
}
catch { wom.setEmail(""); }
// department
try
{
wom.setDepartment(reader.GetString(num++));
}
catch { wom.setDepartment(""); }
// supervisor
try
{
wom.setSupervisor(reader.GetString(num++));
}
catch { wom.setSupervisor(""); }
// affiliate
wom.setAffiliate(reader.GetBoolean(num++));
wom.setBilling(reader.GetBoolean(num++));
wom.setStatus(reader.GetBoolean(num++));
try
{
wom.setStatusValue(reader.GetString(num++));
}
catch
{
wom.setStatusValue("");
}
try
{
wom.setBillingFile(reader.GetString(num++));
}
catch
{
wom.setBillingFile("");
}
try
{
wom.setCommon(reader.GetString(num++));
}
catch
{
wom.setCommon("");
}
try
{
wom.setSection(reader.GetString(num++));
}
catch
{
wom.setSection("");
}
//cust = wom.getCustNum();
// get any extras for each order if the exist
sql = "SELECT * FROM Extra WHERE orderID = " + wom.getWorkOrderNumber();
OleDbDataReader extrasReader;
// are there any extras attached to the work order
cmd = new OleDbCommand(sql, conn);
try
{
extrasReader = cmd.ExecuteReader();
}
catch { extrasReader = null; }
// has values
if (extrasReader.HasRows)
{
ExtraModel extra;
List<ExtraModel> extList = new List<ExtraModel>();
while (extrasReader.Read())
{
extra = new ExtraModel();
extra.setOrderID((int)extrasReader.GetValue(1));
extra.setDescription(extrasReader.GetString(2));
extra.setPrice((double)extrasReader.GetDecimal(3));
extList.Add(extra);
}
wom.setExtras(extList);
}
// add object to list
workOrderList.Add(wom);
}
}// if
// close connection and return list
conn.Close();
return workOrderList;
}
else
{
workOrderList = null;
return workOrderList;
}
}
答案 0 :(得分:2)
在你的循环中,你创建了另一个OleDbCommand
和一个阅读器,但是你从不关闭它们,这意味着你在数据库上打开一个光标。
Close
/ Dispose
额外的读者和&amp;命令完成后,或者更好,使用using
语法。
您可以将cmd
对象重新用于额外的读者。我不知道这是不是错了,但很难看。
// are there any extras attached to the work order
using (var cmdExtras = new OleDbCommand(sql, conn))
using (var extrasReader = cmdExtras.ExecuteReader()) {
ExtraModel extra;
List<ExtraModel> extList = new List<ExtraModel>();
while (extrasReader.Read())
{
extra = new ExtraModel();
extra.setOrderID((int)extrasReader.GetValue(1));
extra.setDescription(extrasReader.GetString(2));
extra.setPrice((double)extrasReader.GetDecimal(3));
extList.Add(extra);
}
if (extList.Any()) wom.setExtras(extList);
}
答案 1 :(得分:2)
虽然我同意其他人一致认为取代Access应该是该计划的发展路线图,但从经验来看,这种负载本身不应该导致它失败。
我们还没有足够的信息来修复它,所以这就是我要采取的措施。
希望这一点应该指出你的根本原因并为你解决问题。