Beispiel #1
0
        private HashCodeCombiner GetExpressionHash(Expression expression)
        {
            var queryContext = _queryContextFactory.Create();

            expression = _queryCompiler.ExtractParameters(
                expression,
                queryContext,
                _logger,
                parameterize: false);

            var hashCode        = ExpressionEqualityComparer.Instance.GetHashCode(expression);
            var combiner        = HashCodeCombiner.Start().Add(hashCode);
            var parameterValues = queryContext.ParameterValues;

            if (parameterValues.Count > 0)
            {
                // If query has parameters add to combiner
                foreach (var p in parameterValues)
                {
                    combiner.Add(p.Key);
                    combiner.Add(p.Value);
                }
            }

            return(combiner);
        }
        /// <summary>
        /// parse select statement of queryable
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="ctx"></param>
        /// <returns></returns>
        public static SelectParsingResult Parse <TEntity>(this IQueryable <TEntity> queryable, DbContext ctx, bool ignoreQueryFilters) where TEntity : class
        {
            if (ignoreQueryFilters)
            {
                queryable = queryable.IgnoreQueryFilters();
            }
            SelectParsingResult parsingResult = new SelectParsingResult();
            Expression          query         = queryable.Expression;
            var databaseDependencies          = ctx.GetService <DatabaseDependencies>();
            IQueryTranslationPreprocessorFactory _queryTranslationPreprocessorFactory = ctx.GetService <IQueryTranslationPreprocessorFactory>();
            IQueryableMethodTranslatingExpressionVisitorFactory _queryableMethodTranslatingExpressionVisitorFactory = ctx.GetService <IQueryableMethodTranslatingExpressionVisitorFactory>();
            IQueryTranslationPostprocessorFactory _queryTranslationPostprocessorFactory = ctx.GetService <IQueryTranslationPostprocessorFactory>();
            QueryCompilationContext queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(true);

            IDiagnosticsLogger <DbLoggerCategory.Query> logger = ctx.GetService <IDiagnosticsLogger <DbLoggerCategory.Query> >();
            QueryContext  queryContext  = ctx.GetService <IQueryContextFactory>().Create();
            QueryCompiler queryComipler = ctx.GetService <IQueryCompiler>() as QueryCompiler;
            //parameterize determines if it will use "Declare" or not
            MethodCallExpression         methodCallExpr1 = queryComipler.ExtractParameters(query, queryContext, logger, parameterize: true) as MethodCallExpression;
            QueryTranslationPreprocessor queryTranslationPreprocessor = _queryTranslationPreprocessorFactory.Create(queryCompilationContext);
            MethodCallExpression         methodCallExpr2 = queryTranslationPreprocessor.Process(methodCallExpr1) as MethodCallExpression;
            QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor =
                _queryableMethodTranslatingExpressionVisitorFactory.Create(queryCompilationContext);
            ShapedQueryExpression         shapedQueryExpression1        = queryableMethodTranslatingExpressionVisitor.Visit(methodCallExpr2) as ShapedQueryExpression;
            QueryTranslationPostprocessor queryTranslationPostprocessor = _queryTranslationPostprocessorFactory.Create(queryCompilationContext);
            ShapedQueryExpression         shapedQueryExpression2        = queryTranslationPostprocessor.Process(shapedQueryExpression1) as ShapedQueryExpression;

            IRelationalParameterBasedSqlProcessorFactory _relationalParameterBasedSqlProcessorFactory =
                ctx.GetService <IRelationalParameterBasedSqlProcessorFactory>();
            RelationalParameterBasedSqlProcessor _relationalParameterBasedSqlProcessor = _relationalParameterBasedSqlProcessorFactory.Create(true);

            SelectExpression selectExpression = (SelectExpression)shapedQueryExpression2.QueryExpression;

            selectExpression = _relationalParameterBasedSqlProcessor.Optimize(selectExpression, queryContext.ParameterValues, out bool canCache);
            IQuerySqlGeneratorFactory querySqlGeneratorFactory = ctx.GetService <IQuerySqlGeneratorFactory>();
            IZackQuerySqlGenerator    querySqlGenerator        = querySqlGeneratorFactory.Create() as IZackQuerySqlGenerator;

            if (querySqlGenerator == null)
            {
                throw new InvalidOperationException("please add dbContext.UseBatchEF() to OnConfiguring first!");
            }
            querySqlGenerator.IsForBatchEF = true;
            querySqlGenerator.GetCommand(selectExpression);
            parsingResult.Parameters    = queryContext.ParameterValues;
            parsingResult.PredicateSQL  = querySqlGenerator.PredicateSQL;
            parsingResult.ProjectionSQL = querySqlGenerator.ProjectionSQL;
            TableExpression tableExpression = selectExpression.Tables[0] as TableExpression;

            parsingResult.TableName = tableExpression.Table.Name;

            return(parsingResult);
        }
        private static (string ExpressionKeyHash, Expression ModifiedExpression) getExpressionKeyHash(
            QueryCompiler queryCompiler,
            IEFCacheKeyHashProvider cacheKeyHashProvider,
            Expression expression)
        {
            var queryContextFactory = (IQueryContextFactory)_queryContextFactoryField.GetValue(queryCompiler);
            var queryContext        = queryContextFactory.Create();
            var logger = (IDiagnosticsLogger <DbLoggerCategory.Query>)_loggerField.GetValue(queryCompiler);

            expression = queryCompiler.ExtractParameters(expression, queryContext, logger, parameterize: false);

            var expressionKey   = $"{ExpressionEqualityComparer.Instance.GetHashCode(expression)};";
            var parameterValues = queryContext.ParameterValues;

            if (parameterValues.Any())
            {
                expressionKey = parameterValues.Aggregate(expressionKey,
                                                          (current, item) => current + $"{item.Key}={item.Value?.GetHashCode()};");
            }

            return(cacheKeyHashProvider.ComputeHash(expressionKey), expression);
        }