/// <summary> /// Throw if requests are greater than maximum allowed /// </summary> private void ThrowIfExceeded() { if (AdoPersistenceService.GetConfiguration().MaxRequests == 0 || Interlocked.Read(ref m_currentRequests) < AdoPersistenceService.GetConfiguration().MaxRequests) { Interlocked.Increment(ref m_currentRequests); } else { throw new LimitExceededException("Data layer restricted maximum system requests"); } }
/// <summary> /// Instructs the service /// </summary> protected virtual IEnumerable <TData> QueryInternal(Expression <Func <TData, bool> > query, Guid queryId, int offset, int?count, IPrincipal authContext, out int totalCount, bool fastQuery) { if (query == null) { throw new ArgumentNullException(nameof(query)); } #if DEBUG Stopwatch sw = new Stopwatch(); sw.Start(); #endif PreQueryEventArgs <TData> preArgs = new PreQueryEventArgs <TData>(query, authContext); this.Querying?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort query {0}", query); totalCount = 0; return(null); } // Query object using (var connection = m_configuration.Provider.GetReadonlyConnection()) try { this.ThrowIfExceeded(); connection.Open(); this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "QUERY {0}", query); // Is there an obsoletion item already specified? if ((count ?? 1000) > 25 && AdoPersistenceService.GetConfiguration().PrepareStatements) { connection.PrepareStatements = true; } if (fastQuery) { connection.AddData("loadFast", true); connection.LoadState = LoadState.PartialLoad; } else { connection.LoadState = LoadState.FullLoad; } var results = this.Query(connection, query, queryId, offset, count ?? 1000, out totalCount, true, authContext); var postData = new PostQueryEventArgs <TData>(query, results.AsQueryable(), authContext); this.Queried?.Invoke(this, postData); var retVal = postData.Results.ToList(); // Add to cache foreach (var i in retVal.AsParallel().Where(i => i != null)) { connection.AddCacheCommit(i); } ApplicationContext.Current.GetService <IThreadPoolService>()?.QueueUserWorkItem(o => { foreach (var itm in (o as IEnumerable <IdentifiedData>)) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } }, connection.CacheOnCommit.ToList()); this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "Returning {0}..{1} or {2} results", offset, offset + (count ?? 1000), totalCount); return(retVal); } catch (NotSupportedException e) { throw new DataPersistenceException("Cannot perform LINQ query", e); } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); throw; } finally { #if DEBUG sw.Stop(); this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "Query {0} took {1} ms", query, sw.ElapsedMilliseconds); #endif Interlocked.Decrement(ref m_currentRequests); } }