主要內容一句話概括:
把相對固定的數據在編譯時僅通過查詢一次數據庫填充到公開的靜態只讀泛型集合類型字段中從而杜絕後續可能的數據庫查詢以提高性能。
相關背景:我們的應用程序中常常需要一些類似全國的省份列表這樣的集合數據,而這些數據基本上是固定不變的或者是很長時間才會變一次。對於這樣的數據,開發中我們常用的一個做法就是把這些數據存在數據庫表中,然後查詢填充到需要的地方。我覺得這種做法很髒,因為我們多次去查詢這些固定不變的數據沒有什麼意義,或者進一步我們頂多緩存這些數據以避免一些查詢以提高性能,也就是利用了單件模式的原理(我對模式不太熟悉,感覺緩存好像是跟單件模式本質一樣,不知道這樣理解是否得當,希望回帖指證我啊)。但是無論緩存和單件模式都需要額外的邏輯(緩存方案需要有判斷緩存數據是否存在,添加過期策略等邏輯;單件模式也必須有擁有類似的邏輯)這些邏輯雖然簡單但也影響性能。
解決方案:
用靜態只讀字段存儲數據,在靜態構造函數內連接數據庫完成數據查詢,將數據賦給類的靜態只讀字段。下面摘自MSDN對靜態構造函數的說明:
靜態構造函數(C# 編程指南)
靜態構造函數用於初始化任何靜態數據,或用於執行僅需執行一次的特定操作。在創建第一個實例或引用任何靜態成員之前,將自動調用靜態構造函數。
MSDN連接地址:http://msdn.microsoft.com/zh-cn/library/k9x6w0hc(VS.80).aspx
示例代碼:
Certificate是“證書類”
CertificateTypes是“證書類型”型的泛型集合
CertificateDictionary是字典,鍵是證書類型ID,值是對應證書類型下的證書集合
public static class Certificate
{
public static readonly IList<CertificateType> CertificateTypes = new List<CertificateType>();
public static readonly IDictionary<int, IList<CertificateList>> CertificateDictionary = new Dictionary<int, IList<CertificateList>>();
private static readonly ICertificate dal = DataAccess.CreateCertificate();
static Certificate()
{
CertificateTypes = dal.GetCertificateTypes();
foreach (CertificateType item in CertificateTypes)
{
CertificateDictionary.Add(item.ID, dal.GetCertificateListByCertificateTypeID(item.ID));
}
}
}
該方案的問題:因為數據是在編譯的時候得到的,得到以後就跟數據庫沒有任何關系了(感興趣的朋友可以通過SQL Sever的事件探查器跟蹤一下,時間探查器在SQL Server 2005中的新名字是SQL Server profiler)也就是說如果有一天中國把日本變成了第35個省的話,你把日本添加到省份列表數據庫表後需要重新編譯一下應用程序才能顯示出來。目前我知道的可以讓應用程序重新編譯的方法是:想辦法改變Web.config文件的時間項,比如原封不動的覆蓋一次(重啟Application會丟失全部會話,請慎用)。哪位朋友有好的方法可以通過編程讓應用程序自動重啟的話回復給我哈
總結:如果你的團隊有時間硬編來碼構造類似全國的縣市列表這樣的集合的話就不需要使用數據庫了,上面的解決方案也就不適合你了。需要說明的一點是上面的方法本質也是通過硬編碼構造集合。
希望對您有用