Beispiel #1
0
        public override TResult ExecuteAsync <TResult>(Expression expression, CancellationToken cancellationToken = default)
        {
            var cachingResult = ReadFromCache <TResult>(expression);

            if (cachingResult.HasResult)
            {
                return(cachingResult.WrapAsyncResult(cachingResult.CacheEntry.Value));
            }

            var result = base.ExecuteAsync <TResult>(cachingResult.Expression, cancellationToken);

            if (!cachingResult.CanPut || cancellationToken.IsCancellationRequested)
            {
                return(result);
            }

            using (var scope = new DbContextScope((HookingDbContext)_currentContext.Context, lazyLoading: false))
            {
                var cacheValue = cachingResult.ConvertQueryAsyncResult(result).Await();

                if (cacheValue.Count <= cachingResult.Policy.MaxRows.Value)
                {
                    var entry = new DbCacheEntry
                    {
                        Key       = cachingResult.CacheKey,
                        Value     = cacheValue.Value,
                        ValueType = cacheValue.Value?.GetType()
                    };

                    _cache.Put(cachingResult.CacheKey, entry, cachingResult.Policy);

                    Log(DbCachingEventId.QueryResultCached,
                        "Has put query result to cache. Key: {0}, Type: {1}, Policy: {2}.",
                        cachingResult.CacheKey.Key,
                        typeof(TResult),
                        cachingResult.Policy);
                }
                else
                {
                    Log(DbCachingEventId.MaxRowsExceeded,
                        "Max rows limit exceeded. Will not cache. Actual: {0}, Limit: {1} Key: {2}, Type: {3}.",
                        cacheValue.Count,
                        cachingResult.Policy.MaxRows.Value,
                        cachingResult.CacheKey.Key,
                        typeof(TResult));
                }

                return(cachingResult.WrapAsyncResult(cacheValue.Value));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Executes the query represented by a specified expression tree to cache its results.
        /// </summary>
        /// <param name="expression">An expression tree that represents a LINQ query.</param>
        /// <param name="queryExecutor">How to run the query.</param>
        /// <returns>The value that results from executing the specified query.</returns>
        private TResult ExecuteInternal <TResult>(Expression expression, Func <Expression, TResult> queryExecutor)
        {
            var cachingResult = ReadFromCache <TResult>(expression);

            if (cachingResult.HasResult)
            {
                return(cachingResult.CachedValue);
            }

            var queryResult = queryExecutor(cachingResult.Expression);

            if (!cachingResult.CanPut)
            {
                return(queryResult);
            }

            using (var scope = new DbContextScope((HookingDbContext)_currentContext.Context, lazyLoading: false))
            {
                var cacheValue = cachingResult.ConvertQueryResult(queryResult);

                if (cacheValue.Count <= cachingResult.Policy.MaxRows.Value)
                {
                    var entry = new DbCacheEntry
                    {
                        Key       = cachingResult.CacheKey,
                        Value     = cacheValue.Value,
                        ValueType = cacheValue.Value?.GetType()
                    };

                    _cache.Put(cachingResult.CacheKey, entry, cachingResult.Policy);

                    Log(DbCachingEventId.QueryResultCached,
                        "Has put query result to cache. Key: {0}, Type: {1}, Policy: {2}.",
                        cachingResult.CacheKey.Key,
                        typeof(TResult),
                        cachingResult.Policy);
                }
                else
                {
                    Log(DbCachingEventId.MaxRowsExceeded,
                        "Max rows limit exceeded. Will not cache. Actual: {0}, Limit: {1} Key: {2}, Type: {3}.",
                        cacheValue.Count,
                        cachingResult.Policy.MaxRows.Value,
                        cachingResult.CacheKey.Key,
                        typeof(TResult));
                }

                return((TResult)cacheValue.Value);
            }
        }
Beispiel #3
0
        public void Put(DbCacheKey key, DbCacheEntry value, DbCachingPolicy policy)
        {
            var cacheKey = BuildKey(key.Key);

            using (_cache.AcquireKeyLock(cacheKey))
            {
                _cache.Put(cacheKey, value, new CacheEntryOptions().ExpiresIn(policy.ExpirationTimeout.Value));

                foreach (var set in key.EntitySets)
                {
                    var lookup = GetLookupSet(set);
                    lookup.Add(cacheKey);
                }
            }
        }
Beispiel #4
0
        protected void InvalidateItem(string key, DbCacheEntry entry)
        {
            // Remove item itself from cache
            _cache.Remove(key);

            // Remove this key in all lookups
            foreach (var set in entry.Key.EntitySets)
            {
                var lookup = GetLookupSet(set, false);
                if (lookup != null)
                {
                    lookup.Remove(key);
                }
            }
        }