.Net頻繁訪問數據庫的優化探究(一)


知識點:DataTable、Linq、lamda表達式、Cache

場景:查詢部門的所有員工和管理員,並分配相應的權限

實現過程一般為:查詢部門,遍歷部門(查詢員工、分配權限、查詢管理員、分配權限)

訪問數據庫比較頻繁的環節為遍歷部門里面的查詢員工和管理員,所有我們嘗試在這里進行優化

1.將用戶全部讀取出來存入DataTable對象中,下一次可直接從DataTable中查詢數據而不必再讀取數據庫,但即便存入DataTable對象,DataTable對象也會在頁面刷新或回發時丟失,所以將DataTable對象存入.Net Cache中。(這與存入Session有質的差別)。

代碼:

if (Page.Cache["users"] == null)
     Page.Cache.Insert("users", UsersCom.GetSimpleUser(), null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20));
DataTable dt = (DataTable)Page.Cache["users"];

其中Page.Cache.Insert最后兩個參數指示緩存到期時間;

UsersCom.GetSimpleUser()是從數據庫中查詢數據的方法,返回的是DataTable對象。盡量不要返回所有的字段,而是需要的字段。這里返回的字段包括user_id、unit_id。

2.從Cache中查詢數據,也就是查詢DataTable對象,查詢的方法很多,從最簡單的開始。

代碼:

dt.Select("unit_id=" + unitID);

直接使用DataTable的Select方法查詢數據,返回DataRow數組,如果你並不想要得到DataRow數組,此時你不得不遍歷該數組重新組裝成其它對象。

這個效率也許沒有使用Linq的效率高,既然這樣那就直接使用Lamda表達式吧!

代碼:

dt.AsEnumerable().Where(t => t.Field<decimal>("unit_id") == unitID).Select(t => t.Field<decimal>("user_id")).ToList();

返回List<decimal>對象;

注:你需要using System.Linq;和在解決方案中引用System.Data.DataSetExtensions(不需要在代碼中using)。

當然如果你要使用Linq,代碼如下:

(from t in dt.AsEnumerable()
where t.Field<decimal>("unit_id") == unitID
select t.Field<decimal>("user_id")).ToList();

返回List<decimal>對象;

3.適當的時候使用多線程

該場景實例運行時間較長,所以開啟了新線程。也避免了UI線程的等待。

你可以封裝一個線程執行類,最后將這個類對象存入Session,隨時可以檢測運行狀態。

代碼:

    /// <summary>
    /// Asp.net線程執行類
    /// </summary>
    public class DocWork
    {
        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="method">執行方法</param>
        public DocWork(Action method)
        {
            this.method = method;
        }

        private DateTime startTime;
        /// <summary>
        /// 開始時間
        /// </summary>
        public DateTime StartTime
        {
            get { return startTime; }
        }

        private DateTime endTime;
        /// <summary>
        /// 結束時間
        /// </summary>
        public DateTime EndTime
        {
            get { return endTime; }
        }

        private DateTime errorTime;
        /// <summary>
        /// 發生錯誤時間
        /// </summary>
        public DateTime ErrorTime
        {
            get { return errorTime; }
        }

        private Thread currnetThread;
        /// <summary>
        /// 當前線程
        /// </summary>
        public Thread CurrnetThread
        {
            get { return currnetThread; }
        }

        private string errorInfo;
        /// <summary>
        /// 錯誤信息
        /// </summary>
        public string ErrorInfo
        {
            get { return errorInfo; }
        }

        private Action method;
        /// <summary>
        /// 執行方法
        /// </summary>
        public Action Method
        {
            get { return method; }
            set { method = value; }
        }
        /// <summary>
        /// 開始執行
        /// </summary>
        public void Start()
        {
            if (currnetThread == null || currnetThread.ThreadState == ThreadState.Stopped)
            {
                currnetThread = new Thread(new ThreadStart(WorkMethod));
                currnetThread.Start();
            }
        }
        /// <summary>
        /// 掛起線程
        /// </summary>
        public void Suspend()
        {
            if (currnetThread != null && currnetThread.ThreadState == ThreadState.Running)
            {
                currnetThread.Suspend();
            }
        }
        /// <summary>
        /// 繼續執行掛起線程
        /// </summary>
        public void Resume()
        {
            if (currnetThread != null && currnetThread.ThreadState == ThreadState.Suspended)
            {
                currnetThread.Resume();
            }
        }
        /// <summary>
        /// 終止執行
        /// </summary>
        public void Abort()
        {
            if (currnetThread != null)
            {
                currnetThread.Abort();
            }
        }
        /// <summary>
        /// 線程方法
        /// </summary>
        protected void WorkMethod()
        {
            if (Method != null)
            {
                try
                {
                    startTime = DateTime.Now;
                    Method.Invoke();
                }
                catch (Exception ex)
                {
                    errorTime = DateTime.Now;
                    errorInfo = ex.Message + "|" + ex.Source;
                }
                finally
                {
                    endTime = DateTime.Now;
                }
            }
        }
    }

數據訪問優化的方法很多,且針對不同的環節方法也不同,本文演示的是數據庫數據查詢到頁面處理環節。

 本文地址:.Net頻繁訪問數據庫的優化探究 轉載請標明出處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM