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

Dan*_*zra 27 c# asp.net asp.net-mvc caching asp.net-mvc-4

我建立使用Asp.net MVC 4(C#)我自己的CMS,我想缓存某些数据库中的数据,喜欢:本土化,搜索类别(它的长尾巴,每个类别都有它自己的子和子子类)等..

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

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

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

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

Bre*_*ogt 34

我不得不缓存常见的数据库数据,如下拉列表中显示的数据.我用过MemoryCache.我使用Entity Framework code firstAutofac依赖注入.

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

我的ICacheManager界面:

public interface ICacheManager
{
     T Get<T>(string key);

     void Set(string key, object data, int cacheTime);

     bool IsSet(string key);

     void Remove(string key);

     void Clear();
}
Run Code Online (Sandbox Code Playgroud)

我的CacheManager班级:

public class CacheManager : ICacheManager
{
     private ObjectCache Cache
     {
          get
          {
               return MemoryCache.Default;
          }
     }

     public T Get<T>(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);
          }
     }
}
Run Code Online (Sandbox Code Playgroud)

我的缓存的扩展类:

public static class CacheExtensions
{
     public static T Get<T>(this ICacheManager cacheManager, string key, Func<T> acquire)
     {
          return Get(cacheManager, key, 60, acquire);
     }

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

               cacheManager.Set(key, result, cacheTime);

               return result;
          }
     }
}
Run Code Online (Sandbox Code Playgroud)

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

public class BankRepository : RepositoryBase<Bank>, 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<Bank> 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();
          });
     }
}
Run Code Online (Sandbox Code Playgroud)

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


Dar*_*rov 31

您可以使用内置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
Run Code Online (Sandbox Code Playgroud)

  • *最佳*是一个主观概念。MemoryCache 具有很强的可扩展性,是 .NET 4.0 中引入的新缓存机制。它可以轻松扩展以使用分布式缓存,例如 memcached,如果您在网络场中运行站点,则这是必须的。 (2认同)