從趙劼 的博客中看的的方法灾梦,通過泛型建立一個泛型數(shù)據(jù)緩存,略加改進妓笙。
閑話少說若河,上代碼
最原始的樣子
static class DataCache<TModel>{
public IEnumerable<TModel> Cache{get;set;}
}
哈哈,就這么簡單寞宫,需要自己設(shè)置緩存數(shù)據(jù)并獲取萧福,沒有任何的應(yīng)用邏輯
非常方便的說。
.Net 運行時會安排緩存數(shù)據(jù)的存放辈赋,保證不同類型的數(shù)據(jù)不會搞混鲫忍。
不過這樣太簡單了膏燕,增加一點功能,從 DataContext 中直接加載緩存數(shù)據(jù)悟民。
static class DataCache<TModel>{
private IEnumerable<TModel> Cache{get;set;}
public static IEnumerable<TModel> GetCacheData<TDataContext>(TDataContext dataContext)
where TDataContext : DataContext{
if (dataContext == null){
throw new ArgumentNullException("dataContext");
}
if (CacheData == null){
CacheData = dataContext.GetTable<TModel>().ToList();
}
return CacheData;
}
}
不同的 DataContext 子類加載的數(shù)據(jù)都會放在一起坝辫,但是通常 不同的 DataContext 命名空間不會一樣,也不會有相同的表射亏,所以盡可以放心使用近忙。
最后一個問題,如何清理緩存智润,當數(shù)據(jù)變化時银锻,需要重新加載緩存,沒什么好辦法做鹰,把緩存清理之后,再次訪問的時候就會重新加載數(shù)據(jù)鼎姐。
通常有兩種情況钾麸,本程序數(shù)據(jù)修改和其他客戶端進行的數(shù)據(jù)修改。
沒有數(shù)據(jù)修改的通知炕桨,只好自己清理緩存了饭尝。
基類 IGenericsCache 建立了一個清理緩存方法的列表,每次加載數(shù)據(jù)就會增加一個方法献宫,需要全部清理的時候執(zhí)行一下就可以了钥平。
/// <summary>
/// 泛型數(shù)據(jù)緩存基類 定義 清除全部緩存功能
/// 在繼承類中,實現(xiàn)獲取緩存的方法中 必須增加一個清理緩存的 活動
/// </summary>
public class IGenericsCache{
/// <summary>
/// 保存 清理緩存的 <see cref="Action"/>
/// </summary>
protected static readonly List<Action> ClearCacheActions = new List<Action>();
/// <summary>
/// 清理全部緩存
/// </summary>
public static void ClearAllCache(){
foreach (Action action in ClearCacheActions){
Console.WriteLine(action);
action.Invoke();
}
ClearCacheActions.Clear();
}
}
/// <summary>
/// Linq 數(shù)據(jù)源 靜態(tài)泛型緩存
/// </summary>
/// <typeparam name="TModel"></typeparam>
public class GenericsCache<TModel> : IGenericsCache where TModel : class{
private static IEnumerable<TModel> CacheData { get; set; }
/// <summary>
/// 獲取緩存
/// </summary>
/// <param name="dataContext"></param>
/// <returns></returns>
public static IEnumerable<TModel> GetCacheData<TDataContext>(TDataContext dataContext)
where TDataContext : DataContext{
if (dataContext == null){
throw new ArgumentNullException("dataContext");
}
if (CacheData == null){
CacheData = dataContext.GetTable<TModel>().ToList();
ClearCacheActions.Add(() => CacheData = null);
}
return CacheData;
}
public static IEnumerable<TModel> GetCacheData<TDataContext>(TDataContext dataContext,
Func<TDataContext, IEnumerable<TModel>>
dataAccesser) where TDataContext : DataContext{
if (dataContext == null){
throw new ArgumentNullException("dataContext");
}
if (CacheData == null){
CacheData = dataAccesser.Invoke(dataContext).ToList();
ClearCacheActions.Add(() => CacheData = null);
}
return CacheData;
}
/// <summary>
/// 清理 <see cref="TModel">當前類型</see>的緩沖緩存
/// </summary>
public static void ClearCache(){
CacheData = null;
}
}
以前總是想著 利用一個字典什么的姊途,可以了解哪些數(shù)據(jù)被緩存了涉瘾,后來發(fā)現(xiàn)這樣一來,泛型緩存就沒有意義了捷兰,只是形式上的泛型方法而已立叛,內(nèi)部實現(xiàn)還是需要獲取類型,那還泛型干什么贡茅。
限制秘蛇,程序中不保證 TModel 一定屬于 TDataContext ,如果不屬于顶考,請使用第二個方法
Func<TDataContext, IEnumerable<TModel>> dataAccesser
通過一個類型轉(zhuǎn)換赁还,可以緩存任意類型的數(shù)據(jù),可以完全和 TDataContext 無關(guān)驹沿。