/// <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); } }
/// <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); }
/// <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); }
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)); }
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); }
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); }