コード例 #1
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="materializer">How to run the query.</param>
        /// <returns>The value that results from executing the specified query.</returns>
        public object Materialize(Expression expression, Func <object> materializer)
        {
            lock (_syncLock)
            {
                var cacheKey = _cacheKeyProvider.GetEFCacheKey(_query, expression, _saltKey);
                _debugInfo.EFCacheKey = cacheKey;
                var queryCacheKey = cacheKey.KeyHash;
                var result        = _cacheServiceProvider.GetValue(queryCacheKey);
                if (Equals(result, _cacheServiceProvider.NullObject))
                {
                    _debugInfo.IsCacheHit = true;
                    return(null);
                }

                if (result != null)
                {
                    _debugInfo.IsCacheHit = true;
                    return(result);
                }

                result = materializer();

                _cacheServiceProvider.InsertValue(queryCacheKey, result, cacheKey.CacheDependencies);

                return(result);
            }
        }
コード例 #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="materializer">How to run the query.</param>
        /// <returns>The value that results from executing the specified query.</returns>
        public object Materialize(Expression expression, Func <object> materializer)
        {
            var cacheKey = _cacheKeyProvider.GetEFCacheKey(
                _query,
                expression,
                _efCachePolicy.KeyHashPrefix,
                _efCachePolicy.SaltKey);

            _debugInfo.EFCacheKey = cacheKey;
            var queryCacheKey = cacheKey.KeyHash;
            var result        = _cacheServiceProvider.GetValue(queryCacheKey);

            if (result != null)
            {
                _debugInfo.IsCacheHit = true;
                return(result);
            }

            result = materializer();

            _cacheServiceProvider.StoreRootCacheKeys(cacheKey.CacheDependencies);
            if (_efCachePolicy.AbsoluteExpiration == null)
            {
                _efCachePolicy.AbsoluteExpiration = DateTime.Now.AddMinutes(20);
            }
            _cacheServiceProvider.InsertValue(
                queryCacheKey,
                result,
                cacheKey.CacheDependencies,
                _efCachePolicy.AbsoluteExpiration.Value,
                _efCachePolicy.Priority);

            return(result);
        }
コード例 #3
0
        /// <summary>
        /// Reads command's data from the cache, if any.
        /// </summary>
        public T ProcessExecutingCommands <T>(DbCommand command, DbContext context, T result)
        {
            var allEntityTypes = _sqlCommandsProcessor.GetAllTableNames(context);
            var cachePolicy    = _cachePolicyParser.GetEFCachePolicy(command.CommandText, allEntityTypes);

            if (cachePolicy == null)
            {
                return(result);
            }

            var efCacheKey = _cacheKeyProvider.GetEFCacheKey(command, context, cachePolicy);

            if (!(_cacheService.GetValue(efCacheKey, cachePolicy) is EFCachedData cacheResult))
            {
                _logger.LogDebug($"[{efCacheKey}] was not present in the cache.");
                return(result);
            }

            if (result is InterceptionResult <DbDataReader> )
            {
                if (cacheResult.IsNull)
                {
                    _logger.LogDebug("Suppressed the result with an empty TableRows.");
                    return((T)Convert.ChangeType(InterceptionResult <DbDataReader> .SuppressWithResult(new EFTableRowsDataReader(new EFTableRows())), typeof(T)));
                }

                _logger.LogDebug($"Suppressed the result with the TableRows[{cacheResult.TableRows.TableName}] from the cache[{efCacheKey}].");
                return((T)Convert.ChangeType(InterceptionResult <DbDataReader> .SuppressWithResult(new EFTableRowsDataReader(cacheResult.TableRows)), typeof(T)));
            }

            if (result is InterceptionResult <int> )
            {
                int cachedResult = cacheResult.IsNull ? default : cacheResult.NonQuery;
                                   _logger.LogDebug($"Suppressed the result with {cachedResult} from the cache[{efCacheKey}].");
                                   return((T)Convert.ChangeType(InterceptionResult <int> .SuppressWithResult(cachedResult), typeof(T)));
            }

            if (result is InterceptionResult <object> )
            {
                object cachedResult = cacheResult.IsNull ? default : cacheResult.Scalar;
                                      _logger.LogDebug($"Suppressed the result with {cachedResult} from the cache[{efCacheKey}].");
                                      return((T)Convert.ChangeType(InterceptionResult <object> .SuppressWithResult(cachedResult), typeof(T)));
            }

            _logger.LogDebug($"Skipped the result with {result?.GetType()} type.");

            return(result);
        }
        /// <summary>
        /// Reads command's data from the cache, if any.
        /// </summary>
        public T ProcessExecutingCommands <T>(DbCommand command, DbContext context, T result, [CallerMemberName] string methodName = null)
        {
            var cachePolicy = _cachePolicyParser.GetEFCachePolicy(command.CommandText);

            if (cachePolicy != null)
            {
                var efCacheKey = _cacheKeyProvider.GetEFCacheKey(command, context, cachePolicy);
                if (!(_cacheService.GetValue(efCacheKey, cachePolicy) is EFCachedData cacheResult))
                {
                    _logger.LogInformation($"[{efCacheKey}] was not present in the cache.");
                    return(result);
                }

                if (result is InterceptionResult <DbDataReader> )
                {
                    if (cacheResult.IsNull)
                    {
                        _logger.LogInformation("Suppressed result with an empty TableRows.");
                        return((T)Convert.ChangeType(InterceptionResult <DbDataReader> .SuppressWithResult(new EFTableRowsDataReader(new EFTableRows())), typeof(T)));
                    }

                    _logger.LogInformation($"Suppressed result with a TableRows[{cacheResult.TableRows.TableName}] from the cache[{efCacheKey}].");
                    return((T)Convert.ChangeType(InterceptionResult <DbDataReader> .SuppressWithResult(new EFTableRowsDataReader(cacheResult.TableRows)), typeof(T)));
                }

                if (result is InterceptionResult <int> )
                {
                    int cachedResult = cacheResult.IsNull ? default : cacheResult.NonQuery;
                                       _logger.LogInformation($"Suppressed result with {cachedResult} from the cache[{efCacheKey}].");
                                       return((T)Convert.ChangeType(InterceptionResult <int> .SuppressWithResult(cachedResult), typeof(T)));
                }

                if (result is InterceptionResult <object> )
                {
                    object cachedResult = cacheResult.IsNull ? default : cacheResult.Scalar;
                                          _logger.LogInformation($"Suppressed result with {cachedResult} from the cache[{efCacheKey}].");
                                          return((T)Convert.ChangeType(InterceptionResult <object> .SuppressWithResult(cachedResult), typeof(T)));
                }
            }

            return(result);
        }
コード例 #5
0
        private CacheResult <T> readFromCache <T>(Expression expression)
        {
            var cacheKey = _cacheKeyProvider.GetEFCacheKey(_query, expression, _cachePolicy?.SaltKey);

            _debugInfo.EFCacheKey = cacheKey;
            var queryCacheKey = cacheKey.KeyHash;
            var result        = _cacheServiceProvider.GetValue(queryCacheKey);

            if (Equals(result, _cacheServiceProvider.NullObject))
            {
                _debugInfo.IsCacheHit = true;
                return(new CacheResult <T>(true, cacheKey, default));
            }

            if (result != null)
            {
                _debugInfo.IsCacheHit = true;
                return(new CacheResult <T>(true, cacheKey, (T)result));
            }

            return(new CacheResult <T>(false, cacheKey, default));
        }
コード例 #6
0
        public void TestCacheInvalidationWithTwoRoots()
        {
            _cacheService.InsertValue("EF_key1", "value1", new HashSet <string> {
                "entity1.model", "entity2.model"
            });

            _cacheService.InsertValue("EF_key2", "value2", new HashSet <string> {
                "entity1.model", "entity2.model"
            });


            var value1 = _cacheService.GetValue("EF_key1");

            Assert.IsNotNull(value1);

            var value2 = _cacheService.GetValue("EF_key2");

            Assert.IsNotNull(value2);

            _cacheService.InvalidateCacheDependencies(new[] { "entity2.model" });

            value1 = _cacheService.GetValue("EF_key1");
            Assert.IsNull(value1);

            value2 = _cacheService.GetValue("EF_key2");
            Assert.IsNull(value2);
        }
コード例 #7
0
        public void TestCacheInvalidationWithTwoRoots()
        {
            _cacheService.StoreRootCacheKeys(new[] { "entity1.model", "entity2.model" });
            _cacheService.InsertValue("EF_key1", "value1", new[] { "entity1.model", "entity2.model" }, DateTime.Now.AddMinutes(10));

            _cacheService.StoreRootCacheKeys(new[] { "entity1.model", "entity2.model" });
            _cacheService.InsertValue("EF_key2", "value2", new[] { "entity1.model", "entity2.model" }, DateTime.Now.AddMinutes(10));


            var value1 = _cacheService.GetValue("EF_key1");

            Assert.IsNotNull(value1);

            var value2 = _cacheService.GetValue("EF_key2");

            Assert.IsNotNull(value2);

            _cacheService.InvalidateCacheDependencies(new[] { "entity2.model" });

            value1 = _cacheService.GetValue("EF_key1");
            Assert.IsNull(value1);

            value2 = _cacheService.GetValue("EF_key2");
            Assert.IsNull(value2);

            var keys = _cacheService.GetAllEFCachedKeys();
            var key1 = keys.FirstOrDefault(key => key == "EF_key1");

            Assert.IsNull(key1);
            Assert.AreEqual(0, keys.Count);
        }
        /// <summary>
        /// Reads command's data from the cache, if any.
        /// </summary>
        public T ProcessExecutingCommands <T>(DbCommand command, DbContext context, T result)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var commandText = command.CommandText;
            var cachePolicy = getCachePolicy(context, commandText);

            if (cachePolicy == null)
            {
                _logger.LogDebug($"Skipping a none-cachable command[{commandText}].");
                return(result);
            }

            var efCacheKey = _cacheKeyProvider.GetEFCacheKey(command, context, cachePolicy);

            if (!(_cacheService.GetValue(efCacheKey, cachePolicy) is EFCachedData cacheResult))
            {
                _logger.LogDebug($"[{efCacheKey}] was not present in the cache.");
                return(result);
            }

            if (result is InterceptionResult <DbDataReader> )
            {
                if (cacheResult.IsNull || cacheResult.TableRows == null)
                {
                    _logger.LogDebug("Suppressed the result with an empty TableRows.");
                    using var rows = new EFTableRowsDataReader(new EFTableRows());
                    return((T)Convert.ChangeType(
                               InterceptionResult <DbDataReader> .SuppressWithResult(rows),
                               typeof(T),
                               CultureInfo.InvariantCulture));
                }

                _logger.LogDebug($"Suppressed the result with the TableRows[{cacheResult.TableRows.TableName}] from the cache[{efCacheKey}].");
                using var dataRows = new EFTableRowsDataReader(cacheResult.TableRows);
                return((T)Convert.ChangeType(
                           InterceptionResult <DbDataReader> .SuppressWithResult(dataRows),
                           typeof(T),
                           CultureInfo.InvariantCulture));
            }

            if (result is InterceptionResult <int> )
            {
                int cachedResult = cacheResult.IsNull ? default : cacheResult.NonQuery;
                                   _logger.LogDebug($"Suppressed the result with {cachedResult} from the cache[{efCacheKey}].");
                                   return((T)Convert.ChangeType(
                                              InterceptionResult <int> .SuppressWithResult(cachedResult),
                                              typeof(T),
                                              CultureInfo.InvariantCulture));
            }

            if (result is InterceptionResult <object> )
            {
                var cachedResult = cacheResult.IsNull ? default : cacheResult.Scalar;
                                   _logger.LogDebug($"Suppressed the result with {cachedResult} from the cache[{efCacheKey}].");
                                   return((T)Convert.ChangeType(
                                              InterceptionResult <object> .SuppressWithResult(cachedResult ?? new object()),
                                              typeof(T),
                                              CultureInfo.InvariantCulture));
            }

            _logger.LogDebug($"Skipped the result with {result?.GetType()} type.");

            return(result);
        }