ASP.NET MVC 使用靜態型別快取資料,減少重複讀取資料庫
2025-01-16
筆記如何設計使用靜態型別來快取資料,減少重複讀取資料庫的情況,並且透過 ASP.NET MVC 5 來實作。

說明
本次實作將 System Settings Value 資料表進行靜態型別的快取實作。
首先設計 Service Class,因為 Setttings 是 Key-Value 的形式,所以使用 Dictionary 來儲存。
關鍵是搭配 InitializeAsync
方法,透過 Entity Framework 來讀取資料庫的資料,並且轉換成 Dictionary。
這個方法會在 Application 啟動時執行一次,之後就是沿用記憶體的快取資料,除非有資料異動。
public static class SettingService
{
public static Dictionary<string, string> Settings { get; set; }
/// <summary>
/// Get setting value by key.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
/// <exception cref="KeyNotFoundException"></exception>
public static string Get(string key)
{
if (Settings.ContainsKey(key))
{
return Settings[key];
}
else
{
return $"Setting key '{key}' not found.";
}
}
public static async Task InitializeAsync()
{
using (var db = new WebAppEntities())
{
Settings = await db.Settings.ToDictionaryAsync(s => s.SettingKey, s => s.Value);
}
}
}
接著在 Global.asax.cs
中的 Application_Start
方法中呼叫 InitializeAsync
方法。
透過 Task.Run
就可以在同步方法中呼叫非同步方法 😎
try
{
Task.Run(() => SettingService.InitializeAsync()).Wait();
}
catch (Exception)
{
Debug.WriteLine("Failed to initialize SettingService");
}
接著考量到資料異動的情況,在 Settings 的 Controller 中新增 Private Method 來重新讀取資料。
private void UpdateSettingsInStaticClass()
{
try
{
Task.Run(() => SettingService.InitializeAsync()).Wait();
}
catch (Exception)
{
Debug.WriteLine("Failed to update SettingService");
}
}
之後在 CREATE, EDIT, DELETE 的 POST Action 中呼叫這個方法。
[HttpPost]
public ActionResult Create(Settings settings)
{
if (ModelState.IsValid)
{
...
UpdateSettingsInStaticClass();
return RedirectToAction("Index");
}
return View(settings);
}