Пример #1
0
            /// <summary>
            /// 检查表达式是否能够被缓存。
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            public static CacheableCheckResult Check(Expression expression)
            {
                var checker = new CacheableChecker();

                checker.Visit(expression);
                return(checker.result);
            }
Пример #2
0
        /// <summary>
        /// 尝试获取指定表达式的缓存。
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="func">当缓存不存在时,创建缓存数据的函数。</param>
        /// <returns></returns>
        internal static Delegate TryGetDelegate(Expression expression, Func <LambdaExpression> func)
        {
            var section = ConfigurationUnity.GetSection <TranslatorConfigurationSection>();
            var option  = section == null ? TranslateOptions.Default : section.Options;

            var result = CacheableChecker.Check(expression);

            if (!result.Required || (result.Enabled == null && !option.CacheParsing) || result.Enabled == false)
            {
                return(func().Compile());
            }

            var cacheKey = ExpressionKeyGenerator.GetKey(expression, "Trans");

            cacheKey = NativeCacheKeyContext.GetKey(cacheKey);

            return(MemoryCacheManager.Instance.TryGet(cacheKey, () =>
            {
                var lambdaExp = func() as LambdaExpression;
                var segment = SegmentFinder.Find(expression);
                if (segment != null)
                {
                    //将表达式内的 Segment 替换成参数
                    var segParExp = Expression.Parameter(typeof(IDataSegment), "g");
                    var newExp = SegmentReplacer.Repalce(lambdaExp.Body, segParExp);
                    var parameters = new List <ParameterExpression>(lambdaExp.Parameters);
                    parameters.Insert(1, segParExp);
                    lambdaExp = Expression.Lambda(newExp, parameters.ToArray());
                }

                return lambdaExp.Compile();
            },
                                                      () => new RelativeTime(result.Expired ?? TimeSpan.FromSeconds(option.CacheParsingTimes))));
        }
Пример #3
0
        /// <summary>
        /// 尝试通过表达式获取执行后的结果缓存。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        internal static T TryGet <T>(Expression expression, Func <T> func)
        {
            var section = ConfigurationUnity.GetSection <TranslatorConfigurationSection>();
            var option  = section == null ? TranslateOptions.Default : section.Options;
            var result  = CacheableChecker.Check(expression);

            //没有开启数据缓存
            if ((result.Enabled == null && !option.CacheExecution) || result.Enabled == false)
            {
                return(func());
            }

            var cacheMgr = CacheManagerFactory.CreateManager();

            if (cacheMgr == null)
            {
                return(func());
            }

            var cacheKey = ExpressionKeyGenerator.GetKey(expression, "Exec");

            cacheKey = NativeCacheKeyContext.GetKey(cacheKey);

            Reference(cacheKey, expression);

            var segment = SegmentFinder.Find(expression);
            var pager   = segment as DataPager;

            var cacheFunc = new Func <CacheItem <T> >(() =>
            {
                var data = EnumerateData(func());

                var isEnumerable = typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(IEnumerable <>);
                if (isEnumerable)
                {
                    var elementType = typeof(T).GetEnumerableElementType();
                    var method      = typeof(Enumerable).GetMethod(nameof(Enumerable.ToList)).MakeGenericMethod(elementType);
                    data            = (T)method.Invoke(null, new object[] { data });
                }

                var total = 0;
                if (pager != null)
                {
                    total = pager.RecordCount;
                }

                return(new CacheItem <T> {
                    Data = data, Total = total
                });
            });

            var cacheItem = cacheMgr.TryGet(cacheKey, cacheFunc, () => new RelativeTime(result.Expired ?? TimeSpan.FromSeconds(option.CacheExecutionTimes)));

            if (pager != null)
            {
                pager.RecordCount = cacheItem.Total;
            }

            return(cacheItem.Data);
        }
Пример #4
0
        /// <summary>
        /// 判断是否被缓存。
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        internal static bool CanCache(Expression expression)
        {
            var section = ConfigurationUnity.GetSection <TranslatorConfigurationSection>();
            var option  = section == null ? TranslateOptions.Default : section.Options;
            var result  = CacheableChecker.Check(expression);

            return(typeof(IQueryable).IsAssignableFrom(expression.Type) && (result.Enabled == true || (result.Enabled == null && option.CacheExecution)));
        }
Пример #5
0
            /// <summary>
            /// 检查表达式是否能够被缓存。
            /// </summary>
            /// <param name="evaluator"></param>
            /// <param name="expression"></param>
            /// <returns></returns>
            public static CacheableCheckResult Check(IExecuteCacheEvaluator evaluator, Expression expression)
            {
                var checker = new CacheableChecker {
                    _evaluator = evaluator
                };

                checker.Visit(expression);
                return(checker._result);
            }
Пример #6
0
        /// <summary>
        /// 异步的,尝试通过表达式获取执行后的结果缓存。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression"></param>
        /// <param name="context"></param>
        /// <param name="creator"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        async Task <T> IExecuteCache.TryGetAsync <T>(Expression expression, ExecuteCacheContext context, Func <CancellationToken, Task <T> > creator, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var section = ConfigurationUnity.GetSection <TranslatorConfigurationSection>();
            var option  = section == null ? TranslateOptions.Default : section.Options;

            if (context.Enabled == true || (context.Enabled == null && option.CacheExecution))
            {
                TryExpire(expression);
            }

            var evaluator = _serviceProvider.TryGetService <IExecuteCacheEvaluator>();

            var result = CacheableChecker.Check(evaluator, expression);

            //没有开启数据缓存
            if ((result.Enabled == null && (context.Enabled == false || (context.Enabled == null && !option.CacheExecution))) ||
                result.Enabled == false || _cacheMgr == null)
            {
                return(await creator(cancellationToken));
            }

            var generator = _serviceProvider.TryGetService <IExecuteCacheKeyGenerator>(() => ExpressionKeyGenerator.Instance);
            var cacheKey  = _serviceProvider.GetCacheKey(generator.Generate(expression, CACHE_KEY));

            Tracer.Debug($"DefaultExecuteCache access to '{cacheKey}'");

            var segment = SegmentFinder.Find(expression);
            var pager   = segment as DataPager;

            using var edps = new EntityDeserializeProcessorScope();
            var cacheItem = _cacheMgr.TryGet(cacheKey,
                                             () => HandleCacheItem(cacheKey, expression, creator(cancellationToken).AsSync(), pager),
                                             () => new RelativeTime(GetExpire(result, option, context)));

            if (pager != null)
            {
                pager.RecordCount = cacheItem.Total;
            }

            TryStartRunner();

            return(cacheItem.Data);
        }
Пример #7
0
        /// <summary>
        /// 尝试获取指定表达式的缓存。
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="context"></param>
        /// <param name="creator">当缓存不存在时,创建缓存数据的函数。</param>
        /// <returns></returns>
        Delegate IQueryCache.TryGetDelegate(Expression expression, QueryCacheContext context, Func <LambdaExpression> creator)
        {
            var section = ConfigurationUnity.GetSection <TranslatorConfigurationSection>();
            var option  = section == null ? TranslateOptions.Default : section.Options;

            var result = CacheableChecker.Check(expression);

            if (!result.Required ||
                (result.Enabled == null && (context.Enabled == false || (context.Enabled == null && !option.CacheParsing))) ||
                result.Enabled == false)
            {
                return(creator().Compile());
            }

            var generator = _serviceProvider.TryGetService <IQueryCacheKeyGenerator>(() => ExpressionKeyGenerator.Instance);
            var cacheKey  = _serviceProvider.GetCacheKey(generator.Generate(expression, "Trans"));

            Tracer.Debug($"QueryCache access to '{cacheKey}'");
            var cacheMgr = _serviceProvider.TryGetService <IMemoryCacheManager>(() => MemoryCacheManager.Instance);

            return(cacheMgr.TryGet(cacheKey, () =>
            {
                var lambdaExp = creator() as LambdaExpression;
                var segment = SegmentFinder.Find(expression);
                if (segment != null)
                {
                    //将表达式内的 Segment 替换成参数
                    var segParExp = Expression.Parameter(typeof(IDataSegment), "g");
                    var newExp = SegmentReplacer.Repalce(lambdaExp.Body, segParExp);
                    var parameters = new List <ParameterExpression>(lambdaExp.Parameters);
                    parameters.Insert(1, segParExp);
                    lambdaExp = Expression.Lambda(newExp, parameters.ToArray());
                }

                return lambdaExp.Compile();
            },
                                   () => new RelativeTime(GetExpire(result, option, context))));
        }