数据库太大无法处理? C#或OLEDBCommand

时间:2016-01-05 15:57:19

标签: c# oledbcommand

我创建了一个相当简单的程序来每年处理报告。直到最近它才起作用,但随着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;
        }
    }

2 个答案:

答案 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应该是该计划的发展路线图,但从经验来看,这种负载本身不应该导致它失败。

我们还没有足够的信息来修复它,所以这就是我要采取的措施。

  1. 将SELECT *查询替换为实际字段列表
  2. 升级try..catch块以记录更多信息,包括给定的InnerExceptions。
  3. 在查询中添加TOP参数,以便准确了解导致其失败的记录数。当你找到你失败的神奇的第一个记录时,调整查询只返回那条记录。它肯定是引起问题的音量,还是个人记录?
  4. 希望这一点应该指出你的根本原因并为你解决问题。