public override TResult Execute <TResult>(Expression query) { Check.NotNull(query, nameof(query)); var queryContext = _queryContextFactory.Create(); // search for cacheable operator and extract parameter var cachableExpressionVisitor = new CachableExpressionVisitor(); query = cachableExpressionVisitor.GetExtractCachableParameter(query, out bool isCacheable, out CacheableOptions options); query = _queryModelGenerator.ExtractParameters(_logger, query, queryContext); // if cacheable operator is part of the query use cache logic if (isCacheable) { // generate key to identify query var queryKey = _cacheProvider.CreateQueryKey(query, queryContext.ParameterValues); if (_cacheProvider.TryGetCachedResult <TResult>(queryKey, out TResult cacheResult)) { _logger.Logger.Log <object>(LogLevel.Debug, CacheableEventId.CacheHit, queryKey, null, _logFormatter); //cache was hit, so return cached query result return(cacheResult); } else // cache was not hit { var cacheKey = _compiledQueryCacheKeyGenerator.GenerateCacheKey(query, false); var compiledQuery = _compiledQueryCache.GetOrAddQuery(cacheKey, () => CompileQueryCore <TResult>(query, _queryModelGenerator, _database, _logger, _contextType)); // excecute query var queryResult = compiledQuery(queryContext); // add query result to cache if (ShouldResultBeCached(queryResult, options)) { _cacheProvider.SetCachedResult <TResult>(queryKey, queryResult, options.TimeToLive); } _logger.Logger.Log <object>(LogLevel.Debug, CacheableEventId.QueryResultCached, queryKey, null, _logFormatter); return(queryResult); } } else { // return default query result var cacheKey = _compiledQueryCacheKeyGenerator.GenerateCacheKey(query, false); var compiledQuery = _compiledQueryCache.GetOrAddQuery(cacheKey, () => CompileQueryCore <TResult>(query, _queryModelGenerator, _database, _logger, _contextType)); return(compiledQuery(queryContext)); } }
public override Task <TResult> ExecuteAsync <TResult>(Expression query, CancellationToken cancellationToken) { Check.NotNull(query, nameof(query)); var queryContext = _queryContextFactory.Create(); queryContext.CancellationToken = cancellationToken; // search for cacheable operator and extract parameter var cachableExpressionVisitor = new CachableExpressionVisitor(); query = cachableExpressionVisitor.GetExtractCachableParameter(query, out bool isCacheable, out CacheableOptions options); query = _queryModelGenerator.ExtractParameters(_logger, query, queryContext); // if cacheable operator is part of the query use cache logic if (isCacheable) { // generate key to identify query var queryKey = _cacheProvider.CreateQueryKey(query, queryContext.ParameterValues); if (_cacheProvider.TryGetCachedResult <TResult>(queryKey, out TResult cacheResult)) { _logger.Logger.Log <object>(LogLevel.Debug, CacheableEventId.CacheHit, queryKey, null, _logFormatter); //cache was hit, so return cached query result return(Task.FromResult <TResult>(cacheResult)); } else // cache was not hit { var cacheKey = _compiledQueryCacheKeyGenerator.GenerateCacheKey(query, true); var compiledQuery = _compiledQueryCache.GetOrAddAsyncQuery(cacheKey, () => CompileAsyncQueryCore <IAsyncEnumerable <TResult> >(query, _queryModelGenerator, _database)); // excecute query return(ExecuteSingletonAsyncQuery(queryContext, compiledQuery, _logger, _contextType, _logFormatter, _cacheProvider, queryKey, options)); } } else { // return default query result var cacheKey = _compiledQueryCacheKeyGenerator.GenerateCacheKey(query, true); var compiledQuery = _compiledQueryCache.GetOrAddAsyncQuery(cacheKey, () => CompileAsyncQueryCore <IAsyncEnumerable <TResult> >(query, _queryModelGenerator, _database)); // parameter 'cacheProvider' is null, the result will not be cached return(ExecuteSingletonAsyncQuery(queryContext, compiledQuery, _logger, _contextType, _logFormatter, null, null, null)); } }