我有一个页面需要经常对大型数据集运行查询。为了减轻数据库的负担,我设置了一个每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);
}
答案 0 :(得分:0)
我相信您正在使用相同的活动连接运行DML或DDL sql查询。而且MARS不允许这样做。您可以执行多个select语句或批量插入,但如果您运行多个更新,删除语句或您的SQL执行将抛出此类错误。即使您在同一命令上运行select语句时运行更新sql查询,也会出现此错误。欲了解更多信息,请阅读
http://msdn.microsoft.com/en-us/library/h32h3abf(v=vs.110).aspx