簡體   English   中英

花費太長時間使用C#WPF應用程序Visual Studio寫入Access數據庫

[英]Take too long time to write in to Access Data Base using C# WPF application, Visual Studio,

我有一個使用C#和VS的WPF應用程序。 我正在使用Access數據庫。 我有一個循環,最長要運行500MS,但是要花570 +-

在我的程序中,我總共有〜340MS的等待時間,還有超過160MS的等待時間可以優化

在用秒表檢查后,我發現當我將數據寫入Access數據庫時,它需要大約50MS(我有3次寫入)。 我不知道如何優化我的數據庫寫入

連接和使用數據庫的我的類是一個看起來像這樣的外部DLL文件(我還給出了一個采用50MS運行時的方法示例,命名為“AddDataToLocalHeaderResult”):

    namespace DataBaseManager
    {
        public class LocalPulserDBManager
        {
            private string localConnectionString;
            private string databaseName = $@"C:\Pulser\LocalPulserDB.mdb";
            private  readonly int _30DaysBack = -30;

            private static readonly Lazy<LocalPulserDBManager> lazy =new Lazy<LocalPulserDBManager>(() => new LocalPulserDBManager());

            public static LocalPulserDBManager LocalPulserDBManagerInstance { get { return lazy.Value; } }

            private void CreateConnectionString()
            {
                localConnectionString = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={databaseName};Persist Security Info=True";
            }

            private LocalPulserDBManager()
            {
                CreateConnectionString();
            }

public  void AddDataToLocalHeaderResult(string reportNumber,string reportDescription, 
            string catalog,string workerName,int machineNumber, Calibration c,string age)
        {
            if (IsHeaderLocalDataExist(reportNumber, catalog, machineNumber, c) == false)
            {
                using (OleDbConnection openCon = new OleDbConnection(localConnectionString))
                {
                    string query = "INSERT into [HeaderResult] ([ReportNumber],[ReportDescription],[CatalogNumber], " +
                        "[WorkerName], [LastCalibrationDate], [NextCalibrationDate], [MachineNumber], [Age]) " +
                        "VALUES (@report ,@reportDescription ,@catalog, @workerName," +
                        " @LastCalibrationDate, @NextCalibrationDate, @machineNumber, @age)";

                    using (OleDbCommand command = new OleDbCommand(query))
                    {
                        command.Parameters.AddWithValue("@report", reportNumber);
                        command.Parameters.AddWithValue("@reportDescription", reportDescription);
                        command.Parameters.AddWithValue("@catalog", catalog);
                        command.Parameters.AddWithValue("@workerName", workerName); 
                        command.Parameters.AddWithValue("@LastCalibrationDate", c.LastCalibrationDate);
                        command.Parameters.AddWithValue("@NextCalibrationDate", c.NextCalibrationDate);
                        command.Parameters.AddWithValue("@machineNumber", machineNumber);
                        command.Parameters.AddWithValue("@age", age);
                        command.Connection = openCon;
                        openCon.Open();
                        int recordsAffected = command.ExecuteNonQuery();
                        openCon.Close();
                    }
                }
            }
        }

    ....
    ....
    METHODS
    .... 

        }
    }

在我的可執行程序中,我使用它:

我有這樣的用法: using static DataBaseManager.LocalPulserDBManager;

在我的代碼中,我執行像LocalPulserDBManagerInstance.AddDataToLocalHeaderResult(ReportNumber, Date_Description,CatalogNumber, WorkerName, (int)MachineNumber, calibrationForSave, AgeCells);

我的一個訪問數據庫表看起來像這樣: 在此輸入圖像描述

該表中的一行如下所示: 在此輸入圖像描述

50MS在那種情況下是正常的運行時間嗎? 如果這里缺少任何信息請告訴我......

*********************編輯**************************

我已經更改了我的AddDataToLocalHeaderResult方法,因為第一個命令告訴我我得到了相同的結果

public  void AddDataToLocalHeaderResult(string reportNumber,string reportDescription, 
            string catalog,string workerName,int machineNumber, Calibration c,string age)
        {
            if (IsHeaderLocalDataExist(reportNumber, catalog, machineNumber, c) == false)
            {
                using (OleDbConnection openCon = new OleDbConnection(localConnectionString))
                {
                    string query = "INSERT into [HeaderResult] ([ReportNumber],[ReportDescription],[CatalogNumber], " +
                        "[WorkerName], [LastCalibrationDate], [NextCalibrationDate], [MachineNumber], [EditTime], [Age]) " +
                        "VALUES (@report ,@reportDescription ,@catalog, @workerName," +
                        " @LastCalibrationDate, @NextCalibrationDate, @machineNumber,@edittime, @age)";
                    DateTime dt = DateTime.Now;
                    DateTime edittime = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);

                    using (OleDbCommand command = new OleDbCommand(query))
                    {
                        command.Parameters.AddWithValue("@report", reportNumber);
                        command.Parameters.AddWithValue("@reportDescription", reportDescription);
                        command.Parameters.AddWithValue("@catalog", catalog);
                        command.Parameters.AddWithValue("@workerName", workerName); 
                        command.Parameters.AddWithValue("@LastCalibrationDate", c.LastCalibrationDate);
                        command.Parameters.AddWithValue("@NextCalibrationDate", c.NextCalibrationDate);
                        command.Parameters.AddWithValue("@machineNumber", machineNumber);
                        command.Parameters.AddWithValue("@edittime", edittime);
                        command.Parameters.AddWithValue("@age", age);
                        command.Connection = openCon;
                        openCon.Open();
                        int recordsAffected = command.ExecuteNonQuery();
                        openCon.Close();
                    }
                }
            }
        }

使用此處顯示的方法,您一次要添加一行。 因此,服務器正在打開與數據庫的連接,將數據寫入內存,然后再寫入物理文件(mdb),然后更新索引。 這是你要嘗試執行的每行完整的四個步驟。 更糟糕的是,將數據寫入物理文件非常耗時。

我認為如果您使用其他方法,請對要插入的整個數據集執行這四個步驟(連接,內存,數據寫入,重新索引)。 因此,假設您要添加1000條記錄,而不是4000個步驟(4x1000),則可以將該處理減少到1400個處理步驟(1個連接,超快的1000個內存寫入,1個數據文件寫入,1個索引修訂)。

下面的代碼粗略地概括了我在說什么:

class Program
{
    static void Main(string[] args)
    {
        //memory-only list for data loading
        List<HeaderResult> mylist = new List<HeaderResult>(){ new HeaderResult("report1","desc of report","ete"), new HeaderResult("report2", "desc of report2", "ete2")};
        var tableForInsert = new DataTable();
        using (SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT * from  HeaderResult", "my conneciton string")) {
            dataAdapter.Fill(tableForInsert);

            //now I have a live copy of the table into which I want to insert data
            //blast in the data
            foreach (HeaderResult hr in mylist) {
                tableForInsert.Rows.Add(hr);
            }

            //now all the data is written at once and sql will take care of the indexes after the datat's written
            dataAdapter.Update(tableForInsert);
        }
}

//class should have same fields as your table
class HeaderResult
{
    string report;
    string reportDescription;
    string etc;
    public HeaderResult(string rpt, string desc, string e)
    {
        report = rpt;
        reportDescription = desc;
        etc = e;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM