/// <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); }
public override Expression Process(Expression query) { var expander = new ExpressionExpander(); return(_innerPreprocessor.Process(expander.Visit(query))); }