首次使用后,缓存的DataSet表行消失

时间:2012-08-30 13:26:34

标签: c# asp.net caching

我正在缓存一个非常昂贵的查询,在我们的一个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;            
    }
}

提前感谢每个人的帮助。

2 个答案:

答案 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;
}

并不是说这与你正在做的事情有很多不同,但这对我有用。