如果可用,从缓存中获取数据,否则从数据库中获取

时间:2013-12-17 00:22:29

标签: asp.net entity-framework

我有一个页面需要经常对大型数据集运行查询。为了减轻数据库的负担,我设置了一个每5分钟刷新一次的缓存。 逻辑是: 进行调用时,检查缓存中是否有数据,如果是,则在缓存上运行queryu。如果没有,请在我的存储库上运行查询时启动从数据库中的所有行获取的任务,以获得该调用所需的数据。获取所有行后,将其放入缓存中,以便在下次调用时访问它。问题是我有时会得到:“Message =”已经有一个与此命令关联的开放DataReader必须先关闭。“我想这是因为它同时向同一个存储库运行两个查询(一个用于所有行和一个查询)。我已经在我的连接字符串中启用了MARS。

我的代码

       public IQueryable<TrackDto> TrackDtos([FromUri] int[] Ids)
    {
            if (HttpContext.Current.Cache["Tracks"] != null && ((IQueryable<TrackDto>)HttpContext.Current.Cache["Tracks"]).Any())
            {
                var trackDtos = Ids.Length > 0
                    ? ((IQueryable<TrackDto>)HttpContext.Current.Cache["Tracks"]).Where(trackDto => Ids.Contains(trackDto.Id).AsQueryable()
                    : ((IQueryable<TrackDto>)HttpContext.Current.Cache["Tracks"]).AsQueryable();
                return trackDtos;
            }
            else
            {
                UpdateTrackDtoCache(DateTime.Today);
                var trackDtos = Ids.Length > 0
                    ? WebRepository.TrackDtos.Where(trackDto => trackDto.Date == DateTime.Today && Ids.Contains(trackDto.Id)).AsQueryable()
                    : WebRepository.TrackDtos.Where(trackDto => trackDto.Date == DateTime.Today).AsQueryable().AsQueryable();
                return trackDtos;
            }
    }

    private IQueryable<TrackDto> MapTrackDtosFromDb(DateTime date)
    {
        return WebRepository.TrackDtos.Where(tdto => tdto.Date == date.Date);
    }

    private void UpdateTrackDtoCache(DateTime date)
    {
        if (CacheIsUpdating)
            return;
            CacheIsUpdating = true;
            var task = Task.Factory.StartNew(
                state =>
                {
                    var context = (HttpContext)state;
                    context.Cache.Insert("Tracks", MapTrackDtosFromDb(date), null, Cache.NoAbsoluteExpiration,
                        new TimeSpan(0, 5, 0));
                    CacheIsUpdating = false;
                },
                HttpContext.Current);
    }

1 个答案:

答案 0 :(得分:0)

我相信您正在使用相同的活动连接运行DML或DDL sql查询。而且MARS不允许这样做。您可以执行多个select语句或批量插入,但如果您运行多个更新,删除语句或您的SQL执行将抛出此类错误。即使您在同一命令上运行select语句时运行更新sql查询,也会出现此错误。欲了解更多信息,请阅读

http://msdn.microsoft.com/en-us/library/h32h3abf(v=vs.110).aspx