有些資料需要大量運算,但是變動機會極低的時候,常會把運算結果存起來,下次直接抓出結果即可。
如果有使用Windows Azure,這邊提供一個快取方式。
參考:
如何使用 Azure Redis 快取
首先建立
Redis Cache Service
安裝
StackExchange.Redis並加入參考
先來看一下Code:
/// <summary>
/// Cache Redis 連線字串,來自Web.config > AppSettings > CacheRedisConnectionString
/// </summary>
private static string _CacheRedisConnectionString = "{名稱}.redis.cache.windows.net,ssl=true,password={密碼}";
/// <summary>
/// Cache Redis 預設保留時間
/// </summary>
private static int _CacheRedisTimeOut = 60;
/// <summary>
/// Cache Redis 連線(類似SQLConnection)
/// </summary>
private static ConnectionMultiplexer CacheRedisConnection;
/// <summary>
/// Cache Redis 存取(類似entity framework的DbContext)
/// </summary>
public static IDatabase CacheRedis;
/// <summary>
/// 設定快取初始連線
/// </summary>
public static void Initialize()
{
if(CacheRedisConnection == null)
{
CacheRedisConnection = ConnectionMultiplexer.Connect(_CacheRedisConnectionString);
if(CacheRedis == null)
{
CacheRedis = CacheRedisConnection.GetDatabase();
}
}
}
/// <summary>
/// 序列化物件
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private static string Serialize(object value)
{
if (value == null)
return null;
return JsonConvert.SerializeObject(value);
}
/// <summary>
/// 字串反序列化為物件
/// </summary>
/// <typeparam name="T">回傳物件型別</typeparam>
/// <param name="value">字串資料</param>
/// <returns>物件</returns>
private static T Deserialize<T>(string value)
{
if (string.IsNullOrWhiteSpace(value)) return default(T);
return JsonConvert.DeserializeObject<T>(value);
}
/// <summary>
/// 取得指定型別快取物件
/// </summary>
/// <typeparam name="T">回傳物件型別</typeparam>
/// <param name="key">快取名稱</param>
/// <returns>回傳快取資料</returns>
public static T GetCache<T>(string key)
{
string value = GetCache(string key);
if(string.IsNullOrWhiteSpace(value) == true) return null;
return Deserialize<T>(GetCache(string key));
}
/// <summary>
/// 取得快取物件
/// </summary>
/// <param name="key">快取名稱</param>
/// <returns>回傳快取資料</returns>
public static string GetCache(string key)
{
//cache為null 或 key為空 或 Cache無資料,回傳null
if (CacheRedis == null || string.IsNullOrWhiteSpace(key) == true || CacheRedis.KeyExists(key) == false) return null;
return CacheRedis.StringGet(key);
}
/// <summary>
/// 設定快取物件,(選用)設定系統預設快取保留時間
/// </summary>
/// <param name="key">快取名稱</param>
/// <param name="value">要快取的資料</param>
/// <param name="defaultexpiry">是否設定預設快取保留時間</param>
public static void SetCache(string key, object value, bool defaultexpiry = true)
{
SetCache(key, value, 0, defaultexpiry);
}
/// <summary>
/// 設定快取物件,並設定快取保留時間
/// </summary>
/// <param name="key">快取名稱</param>
/// <param name="value">要快取的資料</param>
/// <param name="expiry">快取保留時間(分鐘)</param>
public static void SetCache(string key, object value, int expiry)
{
if (expiry <= 0) throw new Exception("CacheRedisHelpers.SetCache(string key, object value, int expiry) error : No Set Expiry");
SetCache(key, value, expiry, false);
}
/// <summary>
/// (private)設定快取物件
/// </summary>
/// <param name="key">快取名稱</param>
/// <param name="value">要快取的資料</param>
/// <param name="expiry">快取保留時間(分鐘)</param>
/// <param name="defaultexpiry">是否設定預設快取保留時間</param>
private static void SetCache(string key, object value, int expiry, bool defaultexpiry)
{
//CacheRedis為null 或 key為空,則不處理
if (CacheRedis != null && string.IsNullOrWhiteSpace(key) == false)
{
//value不為null,則設定快取,反之刪除
if (value != null)
{
//物件轉字串
string strvalue = value as string ?? Serialize(value);
//存入Cache
if (defaultexpiry) //使用預設快取保留時間
CacheRedis.StringSet(key, strvalue , TimeSpan.FromMinutes(_CacheRedisTimeOut));
else if (expiry > 0) //使用傳入快取保留時間
CacheRedis.StringSet(key, strvalue , TimeSpan.FromMinutes(expiry));
else //不設定快取保留時間
CacheRedis.StringSet(key, strvalue );
}
else CacheRedis.KeyDelete(key);
}
}
在程式中,寫好建立連線的Method(Initialize),
建立共用序列化與反序列化Method,
取得的部分,如果取不到資料,Redis Cache也是回傳null,Method只是添加一些判斷減少跟Service連線,
儲存的部分,建立2種較彈性的設定保留時間Method,一個是使用預先設定的預設快取保留時間,另一個是自行設定快取保留時間,
完成了Redis Cache存取功能,接下來使用方式如下:
//建立連線
Initialize();
//儲存資料(預設保留時間)
SetCache("key", objvalue, true);
//儲存資料(自訂保留時間)
SetCache("key", objvalue, iexpiry);
//取得資料(String)
GetCache("key");
//取得資料(指定Type)
GetCache("key");
另外,在CacheRedisConnection.GetDatabase(),可以指定不同的DB(int)儲存資料(預設為0),可以將資料區分讓開發者依不同情境區分資料存放位置。