Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Asp.net C#mvc中缓存数据库表以防止许多数据库查询_C#_Asp.net_Asp.net Mvc_Caching_Asp.net Mvc 4 - Fatal编程技术网

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

如何在Asp.net C#mvc中缓存数据库表以防止许多数据库查询,c#,asp.net,asp.net-mvc,caching,asp.net-mvc-4,C#,Asp.net,Asp.net Mvc,Caching,Asp.net Mvc 4,我使用Asp.NETMVC4(c#)构建了自己的cms,我想缓存一些数据库数据,比如:本地化、搜索类别(它是长尾的,每个类别都有自己的子类别和子类别),等等 如果一直查询数据库,那就太过分了,因为每个页面请求可以有30到100个以上的查询,但是用户很少更新这些数据库 那么最好的方法(性能和方便性)是什么呢? 我知道如何使用操作的OutputCache,但在这种情况下,我不需要它,我需要的是缓存html,但我需要的是,例如,我自己的助手@html.Localization(“Newsletter.

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

如果一直查询数据库,那就太过分了,因为每个页面请求可以有30到100个以上的查询,但是用户很少更新这些数据库

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

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


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

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

典型的模式是:

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

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

您有几个选项,但对于一般的数据缓存,您可以使用,或者对于更灵活和更有价值的内容,您可以使用NoSQL之类的实现

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

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


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

我必须缓存常见的数据库数据,比如下拉列表中显示的数据。我使用了
MemoryCache
。我首先使用
实体框架代码
Autofac
进行依赖注入

这是我在解决方案中所做的部分工作,可能对您不起作用,但对我起作用,虽然不完美,但需要大量清理

我的
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();
}
我的缓存的扩展类:

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;
          }
     }
}
公共静态类缓存扩展
{
公共静态T Get(此ICacheManager cacheManager、字符串键、Func acquire)
{
返回Get(cacheManager,key,60,acquire);
}
公共静态T Get(此ICacheManager缓存管理器,字符串键,int cacheTime,Func acquire)
{
if(cacheManager.IsSet(键))
{
返回cacheManager.Get(key);
}
其他的
{
var result=acquire();
设置(键、结果、缓存时间);
返回结果;
}
}
}
这就是我在我的repository类中使用它的方式。此方法返回所有“我的银行”的列表,该列表显示在下拉列表中

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();
          });
     }
}
公共类银行存储库:RepositoryBase,IBankRepository
{
专用只读ICacheManager cacheManager;
private const string BanksAllCacheKey=“banks all”;
公共银行存储库(IDatabaseFactory databaseFactory、ICacheManager cacheManager)
:base(数据库工厂)
{
Check.Argument.IsNotNull(cacheManager,“cacheManager”);
this.cacheManager=cacheManager;
}
公共IEnumerable FindAll()
{
string key=string.Format(BanksAllCacheKey);
返回cacheManager.Get(键,()=>
{
var query=来自DatabaseContext.Banks中的银行
订单银行名称
选择银行;
返回query.ToList();
});
}
}

我希望这有帮助。这是一个非常简单的实现,但对我来说很有效。网上有许多文章介绍如何在
ASP.NET MVC
中使用缓存策略。只是
Google
it.

你目前在做什么,为什么不起作用?Romoku,我对数据库进行简单的c#linq查询,这太过分了,因为每个页面请求都有很多请求。这是最好的方法吗?我可以找到很多方法,但我不知道什么是最好的,最好的是主观的想法。MemoryCache具有很强的可扩展性,是.NET4.0中引入的新缓存机制。它可以很容易地扩展到使用分布式缓存,例如memcached,这是在Web场中运行站点时必须使用的。然后继续使用MemoryCache。MemoryCache对数据库表一无所知。它适用于.NET对象。因此,从理论上讲,如果您将数据库表加载到某个.NET对象(或一组对象)中,您可以将其存储到MemoryCache中,如我的回答所示。实际上,您不应该扩展MemoryCache。您应该扩展ObjectCache。Memcached已经提供了一个可以直接使用的实现。你是对的。我没有正确地表达自己。回答得很好。我很乐意使用这种方法。允许开发人员在需要时“清除缓存”(我一直在为我的[OutputCache]属性争取持续时间…如果您能将持续时间设置为
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();
          });
     }
}