Пример #1
0
        // Main implementation
        private static IEnumerable<T> FromCacheImplementation<T>(CachingMethod cachingMethod, IQueryable<T> query, out string cacheKey, CachingOptions options) where T : class
        {
            Logger.Log(
                "Performing " + cachingMethod + " for " + query.ToString() + " with options " + options.ToLog() + ".", LogLevel.Trace
            );

            // Create NCache entry options
            CachingOptions optionsCloned = (CachingOptions)options.Clone();

            cacheKey = null;
            string queryStoreKey = null;

            if (cachingMethod != CachingMethod.LoadIntoCache)
            {
                // Verify if query can be fetched seperately
                string pkCacheKey;
                if (QueryHelper.CanDirectPkFetch(query, optionsCloned, out pkCacheKey))
                {
                    object pkItem;
                    if (QueryCacheManager.Cache.TryGetValue(pkCacheKey, out pkItem))
                    {
                        List<T> resultSetPk = new List<T>();
                        List<T> resultSetPkTracked = new List<T>();
                        var stateManagerPk = query.GetStateManager();

                        resultSetPk.Add((T)pkItem);

                        foreach (var entity in resultSetPk)
                        {
                            resultSetPkTracked.Add(((StateManager)stateManagerPk).GetRefValue(entity));
                        }
                        return resultSetPkTracked;
                    }
                }
            }

            bool cacheHit = false;
            IDictionary cacheResult = null;

            queryStoreKey = QueryCacheManager.GetQueryCacheKey(query, optionsCloned.QueryIdentifier);
            if (optionsCloned.StoreAs == StoreAs.Collection || optionsCloned.QueryIdentifier == null)
            {
                if (optionsCloned.StoreAs == StoreAs.Collection)
                    cacheKey = queryStoreKey;
                if (optionsCloned.QueryIdentifier == null)
                    optionsCloned.QueryIdentifier = queryStoreKey;
            }

            // Check in cache
            if (cachingMethod != CachingMethod.LoadIntoCache)
            {

                cacheHit = QueryCacheManager.Cache.GetByKey(queryStoreKey, out cacheResult);

            }

            // If not found in cache go for db
            if (!cacheHit)
            {
                var enumerableSet = query.AsEnumerable<T>();

                CacheDependency dbDependency = null;
                if (optionsCloned.CreateDbDependency)
                {
                    RelationalQueryContext queryContext = null;
                    IRelationalCommand command = query.CreateCommand(out queryContext);
                    string connectionString = queryContext.Connection.ConnectionString;
                    dbDependency = GetDependency(NCacheConfiguration.DatabaseType, command.CommandText, connectionString);
                }
                return new NCacheEnumerable<T>(queryStoreKey, query, enumerableSet, optionsCloned, dbDependency);
            }
            // data is found in cache return result set
            else
            {
                // Assume its a collection
                if (cacheResult.Count == 1)
                {
                    foreach (var item in cacheResult.Values)
                    {
                        CacheEntry entry = item as CacheEntry;
                        if (entry != null)
                        {
                            // Confirmed stored as collection just return the value after casting
                            IEnumerable<T> resultSetC = (IEnumerable<T>)entry.Value;
                            // [Umer] i know this tracking is costly but there is no other solution
                            var resultSetCTracked = new List<T>();
                            var stateManagerC = query.GetStateManager();
                            foreach (var entity in resultSetC)
                            {
                                resultSetCTracked.Add(((StateManager)stateManagerC).GetRefValue(entity));
                            }
                            return resultSetCTracked;
                        }
                        break;
                    }
                }

                var resultSetSE = cacheResult.Values.Cast<T>();
                // [Umer] i know this tracking is costly but there is no other solution
                var resultSetSETracked = new List<T>();
                var stateManagerSE = query.GetStateManager();
                foreach (var entity in resultSetSE)
                {
                    resultSetSETracked.Add(((StateManager)stateManagerSE).GetRefValue(entity));
                }
                return resultSetSETracked;
            }
        }
Пример #2
0
        // Main implementation
        private static T FromCacheImplementation <T>(CachingMethod cachingMethod, QueryDeferred <T> query, out string cacheKey, CachingOptions options)
        {
            Logger.Log(
                "Performing " + cachingMethod + " for " + query.ToString() + " with options " + options.ToLog() + ".",
                Microsoft.Extensions.Logging.LogLevel.Trace
                );
            options = (CachingOptions)options.Clone();
            // Always store as collection
            options.StoreAs = StoreAs.Collection;

            bool        cacheHit    = false;
            IDictionary cacheResult = default(Hashtable);

            cacheKey = QueryCacheManager.GetQueryCacheKey(query.Query, options.QueryIdentifier);

            // If user has specified tag, leave it as it is
            // Otherwise overwrite it with 'cacheKey'
            options.QueryIdentifier = options.QueryIdentifier ?? cacheKey;

            /* NOTE: If user stored result with a tag and is trying to query
             *       it without the tag, it's a different query so don't
             *       worry about that.
             */

            // Get result into 'cacheResult' hashtable if it exists
            if (cachingMethod == CachingMethod.FromCache)
            {
                // Get by the tag (more reliable)
                cacheHit = QueryCacheManager.Cache.GetByKey(options.QueryIdentifier, out cacheResult);
            }
            // If result wasn't found OR result was meant to be stored fresh
            if (cachingMethod == CachingMethod.LoadIntoCache || !cacheHit)
            {
                CacheDependency dbDependency = null;

                if (options.CreateDbDependency)
                {
                    IRelationalCommand command = query.Query.CreateCommand(out RelationalQueryContext queryContext);

                    string connectionString = queryContext.Connection.ConnectionString;

                    dbDependency = GetDependency(NCacheConfiguration.DatabaseType, command.CommandText, connectionString);
                }

                object item = query.Execute();

                QueryCacheManager.Cache.SetAsCacheEntry(cacheKey, item ?? Null.Value, options, dbDependency);

                return(item == null ? default(T) : (T)item);
            }
            // If result was meant to be fetched instead of stored fresh AND it was found (somewhat)
            else
            {
                object returnVal = default(T);

                if (cacheResult != default(Hashtable))
                {
                    returnVal = cacheResult.Values.Cast <CacheEntry>().FirstOrDefault().Value;
                }
                return(returnVal != null ? (returnVal is Null ? default(T) : (T)returnVal) : default(T));
            }
        }