我正在缓存一个非常昂贵的查询,在我们的一个Class文件中填充4个不同的DropDown Box。我花了太多时间尝试我所知道的所有事情,让它在没有运气的情况下工作。第一次,DataSet被缓存,一切看起来都很好。如果我刷新页面,代码会传递缓存项的空检查,但缓存的DataSet中没有行,并且下拉列表不会被填充。
据我所知,我这样做就像MSDN和其他网站上的所有示例一样。我只是无法让缓存坚持下去。 DataSet只有140行,所以不会因为大小而被踢出去。我试图将它设置为永不过期而没有运气。如果有人能帮助我,我会非常感激。
我已经检查了应用程序池设置,他们似乎在回收之前给了足够的时间。关于这一点的奇怪之处在于,第一次缓存DataSet时,数据就在那里。当我刷新页面时,DataSet列Headers位于缓存的项目中,但没有Data,因此它传递了null检查。我真的在这个问题上摸不着头脑。我能够缓存一个字符串,但由于某种原因,不是DataSet超过一个请求。通过在Cached项目上设置监视,它会一直挂起,直到第二次调用该方法,并且当方法启动时,它会清空DataSet。
我添加了委托CacheItemRemovedCallback并且无法触发它,除非我手动删除了缓存项。缓存的对象保留在缓存中,它是正在消失的DataSet行。如果打开缓存的DataSet,则它具有列名,没有行。因此,它正在通过
if(cacheItem == null)
检查。我可以缓存一个没有问题的字符串,它会一直保留在缓存中,直到它过期或我手动删除它。我真的很茫然。有没有其他方法让我尝试缓存该项目?我不认为会话会起作用,系统在会话级别使用它的查询成本太高。
public DataSet ReturnPhysicianSpecialtyCodes()
{
string cacheKey = "PhysCodes";
object cacheItem = HttpRuntime.Cache[cacheKey] as DataSet;
if(cacheItem == null)
{
string sqlCommand =
"SELECT DISTINCT SPECIALTY_CODE, SPECIALTY " +
"FROM PHARM.PHYSICIAN_SPECIALTY " +
"ORDER BY SPECIALTY";
cacheItem = OracleHelper.ExecuteDataset(
this.Connection,
CommandType.Text,
sqlCommand);
HttpRuntime.Cache.Insert(
cacheKey,
cacheItem,
null,
Cache.NoAbsoluteExpiration,
new TimeSpan(1,
0, 0),
CacheItemPriority.Default, null);
}
return (DataSet)cacheItem;
}
}
提前感谢每个人的帮助。
答案 0 :(得分:0)
尝试使用其他容器,例如List。使用cmd.ExecuteDatareader填充它并存储在缓存中。奇迹般有效。如果您只需要绑定下拉列表,则使用数据集是一种不好的做法。
答案 1 :(得分:0)
我通常像这样做我的缓存...
public DataSet ReturnPhysicianSpecialtyCodes() {
HttpContext context = HttpContext.Current;
string cacheKey = "PhysCodes";
DataSet cacheItem = (DataSet)context.Cache.Get(cacheKey);
if(cacheItem == null) {
string sqlCommand =
"SELECT DISTINCT SPECIALTY_CODE, SPECIALTY " +
"FROM PHARM.PHYSICIAN_SPECIALTY " +
"ORDER BY SPECIALTY";
cacheItem = OracleHelper.ExecuteDataset(
this.Connection,
CommandType.Text,
sqlCommand);
context.Cache.Add(
cacheKey,
cacheItem,
null,
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal,
null);
}
return (DataSet)cacheItem;
}
并不是说这与你正在做的事情有很多不同,但这对我有用。