0

我正在缓存一个非常昂贵的查询以在我们的一个类文件中填充 4 个不同的下拉框。我花了太多时间尝试我所知道的一切来让它工作但没有运气。第一次通过时,DataSet 被缓存,一切看起来都很好。如果我刷新页面,代码会通过缓存项的 null 检查,但缓存的 DataSet 中没有行,并且不会填充下拉列表。

据我所知,我正在这样做,就像 MSDN 和其他网站上的所有示例一样。我只是无法让缓存粘住。DataSet 只有 140 行,因此不会因大小而被淘汰。我也尝试将其设置为永不过期,也没有运气。如果有人可以帮助我,我将不胜感激。

我检查了应用程序池设置,他们似乎在回收之前给了足够的时间。奇怪的是,当第一次缓存 DataSet 时,数据就在那里。当我刷新页面时,DataSet 列 Headers 在缓存项中,但没有 Data,因此它通过了 null 检查。我真的在这个问题上摸不着头脑。我能够缓存一个字符串,但由于某种原因,数据集不能超过一个请求。从对 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;            
    }
}

提前感谢大家的帮助。

4

2 回答 2

0

尝试使用其他容器,例如 List。使用 cmd.ExecuteDatareader 填充它并存储在缓存中。奇迹般有效。如果您只需要绑定下拉菜单,则使用数据集是一种不好的做法。

于 2012-08-30T15:15:37.730 回答
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;
}

并不是说这与您正在做的事情有很大区别,但这对我有用。

于 2012-08-30T15:16:48.590 回答