如何避免多次重复数据库查询
问题描述:
我们正在使用asp.net mvc实体框架如何避免多次重复数据库查询
我们有很多代表大量静态数据的查询。我想知道什么是避免每次查询数据的最好和最简单的方法。
我们目前使用自定义缓存,但似乎有问题。我想知道别人怎么做到这一点。
比如我有一个拥有超过10,000条记录
其整个网站使用,当应用程序启动时不需要再得到抓取可以进行查询的位置的数据集。
答
只需使用System.Runtime.Caching.MemoryCache
也许这会有所帮助:
void SomeAction()
{
var test1 = LoadIds();
var test2 = LoadIds();
// test1 & test2 should be the same
}
int[] LoadIds() {
var random = new Random();
return MemoryCache.Default.GetCached("LoadIds", 60,() => new int[10].Select(x => random.Next()).ToArray());
}
public static class CacheExtensions {
public static T GetCached<T>(this ObjectCache cache, string key, int cacheTime, Func<T> acquire)
{
if (cache.Contains(key))
return (T) cache[key];
var result = acquire();
if (cacheTime > 0)
cache.Add(new CacheItem(key, result), new CacheItemPolicy {AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime)});
return result;
}
}
现在不是使用该随机初始化...
MemoryCache.Default.GetCached("LoadIds", 60,() => new int[10].Select(x => random.Next()).ToArray());
...你可以使用你的查询。只需确保在最后添加.ToList()或.ToArray(),因为您想要缓存数据而不仅仅是查询。例如
MemoryCache.Default.GetCached("LoadIds", 60,() => dbContext.Persons.Select(x => x.Id).ToArray());
或者在你的情况可能
MemoryCache.Default.GetCached("LoadLocations", 60,() => dbContext.Locations.ToArray());
这上面的扩展方法是不完美的,但。如果两个请求同时访问相同的内容,它可能会加倍加载该数据...
我在大型Web应用程序中使用此方法,同时抽象出MemoryCache以便将其替换为其他像Redis,azure存储或者每个请求缓存的HttpContext.Current.Items类型的缓存。
解决方案显然是缓存。您的自定义缓存有哪些问题? – 2014-10-08 06:33:59
是的,但使用什么,你如何实现这一点。一个开发者定制开发了一个缓存模块,它的表现并不好,因此我正在寻找其他人如何去做。 – 2014-10-08 06:38:08
我们将这种数据作为'''ObjectCache'''中的'''ConcurrentDictionary'''对象存储。我们为您搜索的每个索引/属性使用单独的字典。这些字典是懒加载的。 – 2014-10-08 06:45:57