我们正在使用asp.net mvc实体框架
我们有许多代表大型静态数据的查询。我想知道每次避免查询数据的最佳和最简单的方法是什么。
我们目前使用自定义缓存但似乎有问题。我想知道其他人是如何做到这一点的。
例如,我有一个位置数据集超过10k的记录
它在整个网站中使用,并且可以在应用程序启动时查询,无需再次获取。
答案 0 :(得分:1)
只需使用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(),因为您要缓存数据而不仅仅是查询。 e.g。
MemoryCache.Default.GetCached("LoadIds", 60, () => dbContext.Persons.Select(x => x.Id).ToArray());
或者在你的情况下可能
MemoryCache.Default.GetCached("LoadLocations", 60, () => dbContext.Locations.ToArray());
上面这种扩展方法并不完美。如果两个请求同时访问相同的内容,它可能会加载该数据......
我在大型网络应用程序中使用此方法,同时抽象出MemoryCache,以便将其替换为其他类型的缓存,如Redis,azure存储,甚至每个请求的缓存的HttpContext.Current.Items。