如何缓存数据库表以防止在Asp.net C#mvc中进行许多数据库查询

我使用Asp.net mvc 4(c#)构建自己的cms,我想缓存一些数据库数据,如:本地化,搜索类别(它是长尾,每个类别都有自己的子和子子类别),等等..

一直查询数据库会有点过分,因为每个页面请求可能超过30-100个查询,但用户很少更新这些数据库

那么最好的方法(性能和便利性)是什么?

我知道如何使用动作的OutputCache,但这不是我在这种情况下所需要的,它是缓存html,但我需要的是,例如,我自己的助手@html.Localization("Newsletter.Tite")将采取语言的价值,或与数据交互的任何其他帮助者等。

我认为(不是很确定)我需要缓存我想要的数据,只有在第一次调用应用程序时,然后使用缓存位置,但我没有任何经验。

您可以使用内置的MemoryCache存储从数据库中检索的整个结果集。

典型模式:

 MyModel model = MemoryCache.Default["my_model_key"] as MyModel; if (model == null) { model = GetModelFromDatabase(); MemoryCache.Default["my_model_key"] = model; } // you could use the model here 

我不得不缓存常见的数据库数据,如下拉列表中显示的数据。 我用过MemoryCache 。 我首先使用Entity Framework code first ,使用Autofac进行dependency injection。

这是我在我的解决方案中所做的一部分,可能不适合你,但它对我有用,虽然不完美,但需要大量的清理工作。

我的ICacheManager接口:

 public interface ICacheManager { T Get(string key); void Set(string key, object data, int cacheTime); bool IsSet(string key); void Remove(string key); void Clear(); } 

我的CacheManager类:

 public class CacheManager : ICacheManager { private ObjectCache Cache { get { return MemoryCache.Default; } } public T Get(string key) { return (T)Cache[key]; } public void Set(string key, object data, int cacheTime) { if (data == null) { return; } CacheItemPolicy policy = new CacheItemPolicy(); policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime); Cache.Add(new CacheItem(key, data), policy); } public bool IsSet(string key) { return (Cache.Contains(key)); } public void Remove(string key) { Cache.Remove(key); } public void Clear() { foreach (var item in Cache) { Remove(item.Key); } } } 

我的缓存的扩展类:

 public static class CacheExtensions { public static T Get(this ICacheManager cacheManager, string key, Func acquire) { return Get(cacheManager, key, 60, acquire); } public static T Get(this ICacheManager cacheManager, string key, int cacheTime, Func acquire) { if (cacheManager.IsSet(key)) { return cacheManager.Get(key); } else { var result = acquire(); cacheManager.Set(key, result, cacheTime); return result; } } } 

这就是我在我的存储库类中使用它的方法。 此方法返回所有银行的列表,该列表显示在下拉列表中。

 public class BankRepository : RepositoryBase, IBankRepository { private readonly ICacheManager cacheManager; private const string BanksAllCacheKey = "banks-all"; public BankRepository(IDatabaseFactory databaseFactory, ICacheManager cacheManager) : base(databaseFactory) { Check.Argument.IsNotNull(cacheManager, "cacheManager"); this.cacheManager = cacheManager; } public IEnumerable FindAll() { string key = string.Format(BanksAllCacheKey); return cacheManager.Get(key, () => { var query = from bank in DatabaseContext.Banks orderby bank.Name select bank; return query.ToList(); }); } } 

我希望这有帮助。 这是一个非常简单的实现,但它适用于我。 有很多关于如何在ASP.NET MVC使用缓存策略的文章。 只是Google吧。

在选择缓存实现之前,有几点需要考虑,但是您必须决定的主要事项之一是您希望缓存发生在什么时候 – 数据访问,模型创建或UI生成? 这些地方中的一个或全部?

您有几个选项,但对于常规数据缓存,您可以使用System.Runtime.Caching.MemoryCache ,或者对于更加灵活和有益的东西,您可以查看使用NoSQL之类的实现,如Redis 。

您可以使用MemoryCache进行数据缓存,但可以使用Redis缓存构成视图模型的聚合。 如果您使用Redis,您当然可以使用此处理所有缓存。 好处是所有数据在应用程序重新启动时都会保持不变。 缺点是它成为运行CMS的额外要求。

其他要考虑的因素是一致性(使用一些IoC会有所帮助)并允许数据在更新后无效。 因此有一些更新缓存的方法。

关于最佳方法,在您的情况下,如果您要创建新的CMS应用程序,请从小/简单开始并逐步构建。 你可能不会在第一时间得到完美,但只要你在你的方法中保持一致和清晰,就应该很容易建立在你所做的事情上,或者换掉并尝试不同/更好的事情。