/// <summary> /// Gets an EF query and returns its hashed key to store in the cache. /// </summary> /// <param name="query">The EF query.</param> /// <param name="expression">An expression tree that represents a LINQ query.</param> /// <param name="saltKey">If you think the computed hash of the query is not enough, set this value.</param> /// <returns>Information of the computed key of the input LINQ query.</returns> public EFCacheKey GetEFCacheKey(IQueryable query, Expression expression, string saltKey = "") { var queryCompiler = (QueryCompiler)_queryCompilerField.GetValue(query.Provider); var(expressionKeyHash, modifiedExpression) = getExpressionKeyHash(queryCompiler, _cacheKeyHashProvider, expression); var cachedKey = _keysCacheManager.Get <EFCacheKey>(expressionKeyHash); if (cachedKey != null) { return(cachedKey); } var expressionPrinter = new ExpressionPrinter(); var sql = expressionPrinter.PrintDebug(modifiedExpression); var expressionVisitorResult = EFQueryExpressionVisitor.GetDebugView(expression); var key = $"{sql};{expressionVisitorResult.DebugView};{saltKey}"; var keyHash = _cacheKeyHashProvider.ComputeHash(key); var cacheKey = new EFCacheKey { Key = key, KeyHash = keyHash, CacheDependencies = expressionVisitorResult.Types }; setCache(expressionKeyHash, cacheKey); return(cacheKey); }
public virtual void TestObjectCacheInvalidationWithOneRoot(TestCacheProvider cacheProvider) { var cacheService = EFServiceProvider.GetCacheServiceProvider(cacheProvider); var efCachePolicy = new EFCachePolicy().Timeout(TimeSpan.FromMinutes(10)).ExpirationMode(CacheExpirationMode.Absolute); const string rootCacheKey = "EFSecondLevelCache.Core.AspNetCoreSample.DataLayer.Entities.Product"; cacheService.InvalidateCacheDependencies(new EFCacheKey { CacheDependencies = new HashSet <string> { rootCacheKey } }); var key11888622 = new EFCacheKey { KeyHash = "11888622", CacheDependencies = new HashSet <string> { rootCacheKey } }; var val11888622 = cacheService.GetValue(key11888622, efCachePolicy); Assert.IsNull(val11888622); cacheService.InsertValue( key11888622, new EFCachedData { Scalar = "Test1" }, efCachePolicy); var key44513A63 = new EFCacheKey { KeyHash = "44513A63", CacheDependencies = new HashSet <string> { rootCacheKey } }; var val44513A63 = cacheService.GetValue(key44513A63, efCachePolicy); Assert.IsNull(val44513A63); cacheService.InsertValue( key44513A63, new EFCachedData { Scalar = "Test1" }, efCachePolicy); cacheService.InvalidateCacheDependencies(new EFCacheKey { CacheDependencies = new HashSet <string> { rootCacheKey } }); val11888622 = cacheService.GetValue(key11888622, efCachePolicy); Assert.IsNull(val11888622); val44513A63 = cacheService.GetValue(key44513A63, efCachePolicy); Assert.IsNull(val44513A63); }
public virtual void TestCacheInvalidationWithSimilarRoots(TestCacheProvider cacheProvider) { var cacheService = EFServiceProvider.GetCacheServiceProvider(cacheProvider); var efCachePolicy = new EFCachePolicy().Timeout(TimeSpan.FromMinutes(10)).ExpirationMode(CacheExpirationMode.Absolute); var key1 = new EFCacheKey { KeyHash = "EF_key1", CacheDependencies = new HashSet <string> { "entity1", "entity2" } }; cacheService.InsertValue( key1, new EFCachedData { Scalar = "value1" }, efCachePolicy); var key2 = new EFCacheKey { KeyHash = "EF_key2", CacheDependencies = new HashSet <string> { "entity2" } }; cacheService.InsertValue( key2, new EFCachedData { Scalar = "value2" }, efCachePolicy); var value1 = cacheService.GetValue(key1, efCachePolicy); Assert.IsNotNull(value1); var value2 = cacheService.GetValue(key2, efCachePolicy); Assert.IsNotNull(value2); cacheService.InvalidateCacheDependencies(new EFCacheKey { CacheDependencies = new HashSet <string> { "entity2" } }); value1 = cacheService.GetValue(key1, efCachePolicy); Assert.IsNull(value1); value2 = cacheService.GetValue(key2, efCachePolicy); Assert.IsNull(value2); }
/// <summary> /// Invalidates all of the cache entries which are dependent on any of the specified root keys. /// </summary> /// <param name="cacheKey">Stores information of the computed key of the input LINQ query.</param> public void InvalidateCacheDependencies(EFCacheKey cacheKey) { _readerWriterLockProvider.TryWriteLocked(() => { foreach (var rootCacheKey in cacheKey.CacheDependencies) { if (string.IsNullOrWhiteSpace(rootCacheKey)) { continue; } clearDependencyValues(rootCacheKey); _dependenciesCacheManager.Remove(_keyPrefix + rootCacheKey); } }); }
public virtual void TestInsertingNullValues(TestCacheProvider cacheProvider) { var cacheService = EFServiceProvider.GetCacheServiceProvider(cacheProvider); var efCachePolicy = new EFCachePolicy().Timeout(TimeSpan.FromMinutes(10)).ExpirationMode(CacheExpirationMode.Absolute); var key1 = new EFCacheKey(new HashSet <string> { "entity1", "entity2" }) { KeyHash = "EF_key1" }; cacheService.InsertValue( key1, null, efCachePolicy); var value1 = cacheService.GetValue(key1, efCachePolicy); Assert.IsTrue(value1.IsNull, $"value1 is `{value1}`"); }
/// <summary> /// Adds a new item to the cache. /// </summary> /// <param name="cacheKey">key</param> /// <param name="value">value</param> /// <param name="cachePolicy">Defines the expiration mode of the cache item.</param> public void InsertValue(EFCacheKey cacheKey, EFCachedData value, EFCachePolicy cachePolicy) { _readerWriterLockProvider.TryWriteLocked(() => { if (value == null) { value = new EFCachedData { IsNull = true }; } var keyHash = cacheKey.KeyHash; foreach (var rootCacheKey in cacheKey.CacheDependencies) { _dependenciesCacheManager.AddOrUpdate(_keyPrefix + rootCacheKey, new HashSet <string>(StringComparer.OrdinalIgnoreCase) { keyHash }, updateValue: set => { set.Add(keyHash); return(set); }); } if (cachePolicy == null) { _valuesCacheManager.Add(_keyPrefix + keyHash, value); } else { _valuesCacheManager.Add(new CacheItem <EFCachedData>(_keyPrefix + keyHash, value, cachePolicy.CacheExpirationMode == CacheExpirationMode.Absolute ? ExpirationMode.Absolute : ExpirationMode.Sliding, cachePolicy.CacheTimeout)); } }); }
/// <summary> /// Gets a cached entry by key. /// </summary> /// <param name="cacheKey">key to find</param> /// <returns>cached value</returns> /// <param name="cachePolicy">Defines the expiration mode of the cache item.</param> public EFCachedData GetValue(EFCacheKey cacheKey, EFCachePolicy cachePolicy) { return(_readerWriterLockProvider.TryReadLocked(() => _valuesCacheManager.Get <EFCachedData>(_keyPrefix + cacheKey.KeyHash))); }
/// <summary> /// Cache Result Container /// </summary> /// <param name="canRead">Could read from the cache?</param> /// <param name="cacheKey">EFCacheKey value</param> /// <param name="result">Retrieved result from the cache</param> public CacheResult(bool canRead, EFCacheKey cacheKey, T result) { CanRead = canRead; CacheKey = cacheKey; Result = result; }
private static void setCache(string expressionKeyHash, EFCacheKey value) { _keysCacheManager.Add( new CacheItem <EFCacheKey>(expressionKeyHash, value, ExpirationMode.Sliding, _slidingExpirationTimeSpan)); }