/// <summary> /// Initializes a new instance of the <see cref="CacheKeyStore"/> class. /// </summary> public CacheKeyStore() { _cacheKeysPerTag = new MultiValueHashtable <string, CacheKey>(); _cacheKeyToMemoryCacheKey = new Dictionary <CacheKey, Guid>(); _cacheKeysAndExpireDates = new List <ValuePair <CacheKey, DateTime> >(); _semaphore = new object(); _purgeTimer = new Timer(5.0); _purgeTimer.Elapsed += _purgeTimer_Elapsed; _purgeTimer.Enabled = true; }
/// <summary> /// Retrieves for all available sections all forums with all relevant statistical information. This information is stored per forum in an /// AggregatedForumRow instance. The forum instances are indexed under their sectionid. Only forums which are vieable by the user are returned. /// </summary> /// <param name="availableSections">SectionCollection with all available sections</param> /// <param name="accessableForums">List of accessable forums IDs.</param> /// <param name="forumsWithThreadsFromOthers">The forums for which the calling user can view other users' threads. Can be null</param> /// <param name="userId">The userid of the calling user.</param> /// <returns> /// MultiValueHashtable with per key (sectionID) a set of AggregatedForumRow instance, one row per forum in the section. If a section contains no forums /// displayable to the user it's not present in the returned hashtable. /// </returns> public static async Task <MultiValueHashtable <int, AggregatedForumRow> > GetAllAvailableForumsAggregatedData(EntityCollection <SectionEntity> availableSections, List <int> accessableForums, List <int> forumsWithThreadsFromOthers, int userId) { var toReturn = new MultiValueHashtable <int, AggregatedForumRow>(); // return an empty list, if the user does not have a valid list of forums to access if (accessableForums == null || accessableForums.Count <= 0) { return(toReturn); } // fetch all forums with statistics in a dynamic list, while filtering on the list of accessable forums for this user. // Create the filter separate of the query itself, as it's re-used multiple times. var threadFilter = ThreadGuiHelper.CreateThreadFilter(forumsWithThreadsFromOthers, userId); var qf = new QueryFactory(); var q = qf.Create() .Select(() => new AggregatedForumRow() { ForumID = ForumFields.ForumID.ToValue <int>(), ForumName = ForumFields.ForumName.ToValue <string>(), ForumDescription = ForumFields.ForumDescription.ToValue <string>(), ForumLastPostingDate = ForumFields.ForumLastPostingDate.ToValue <DateTime?>(), // add a scalar query which retrieves the # of threads in the specific forum. // this will result in the query: // ( // SELECT COUNT(ThreadID) FROM Thread // WHERE ForumID = Forum.ForumID AND threadfilter. // ) As AmountThreads AmountThreads = qf.Create() .Select(ThreadFields.ThreadID.Count()) .CorrelatedOver(ThreadFields.ForumID.Equal(ForumFields.ForumID)) .Where(threadFilter) .ToScalar().As("AmountThreads").ToValue <int>(), // add a scalar query which retrieves the # of messages in the threads of this forum. // this will result in the query: // ( // SELECT COUNT(MessageID) FROM Message // WHERE ThreadID IN // ( // SELECT ThreadID FROM Thread WHERE ForumID = Forum.ForumID AND threadfilter // ) // ) AS AmountMessages AmountMessages = qf.Create() .Select(MessageFields.MessageID.Count()) .Where(MessageFields.ThreadID.In( qf.Create() .Select(ThreadFields.ThreadID) .CorrelatedOver(ThreadFields.ForumID.Equal(ForumFields.ForumID)) .Where(threadFilter))) .ToScalar().As("AmountMessages").ToValue <int>(), HasRSSFeed = ForumFields.HasRSSFeed.ToValue <bool>(), SectionID = ForumFields.SectionID.ToValue <int>() }) .Where(ForumFields.ForumID.In(accessableForums)) .OrderBy(ForumFields.OrderNo.Ascending(), ForumFields.ForumName.Ascending()) .CacheResultset(Globals.DefaultCacheDurationOfResultsets); using (var adapter = new DataAccessAdapter()) { var results = await adapter.FetchQueryAsync(q).ConfigureAwait(false); foreach (var forum in results) { toReturn.Add(forum.SectionID, forum); } } return(toReturn); }