Beispiel #1
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitShapedQuery(ShapedQueryExpression shapedQueryExpression)
        {
            Check.NotNull(shapedQueryExpression, nameof(shapedQueryExpression));

            var inMemoryQueryExpression = (InMemoryQueryExpression)shapedQueryExpression.QueryExpression;

            var shaper = new ShaperExpressionProcessingExpressionVisitor(
                inMemoryQueryExpression, inMemoryQueryExpression.CurrentParameter)
                         .Inject(shapedQueryExpression.ShaperExpression);

            shaper = InjectEntityMaterializers(shaper);

            var innerEnumerable = Visit(inMemoryQueryExpression);

            shaper = new InMemoryProjectionBindingRemovingExpressionVisitor().Visit(shaper);

            shaper = new CustomShaperCompilingExpressionVisitor(
                QueryCompilationContext.QueryTrackingBehavior == QueryTrackingBehavior.TrackAll).Visit(shaper);

            var shaperLambda = (LambdaExpression)shaper;

            return(Expression.New(
                       typeof(QueryingEnumerable <>).MakeGenericType(shaperLambda.ReturnType).GetConstructors()[0],
                       QueryCompilationContext.QueryContextParameter,
                       innerEnumerable,
                       Expression.Constant(shaperLambda.Compile()),
                       Expression.Constant(_contextType),
                       Expression.Constant(
                           QueryCompilationContext.QueryTrackingBehavior == QueryTrackingBehavior.NoTrackingWithIdentityResolution),
                       Expression.Constant(_concurrencyDetectionEnabled)));
        }
Beispiel #2
0
        protected override Expression VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
        {
            var inMemoryQueryExpression = (InMemoryQueryExpression)shapedQueryExpression.QueryExpression;

            var shaper = new ShaperExpressionProcessingExpressionVisitor(inMemoryQueryExpression)
                         .Inject(shapedQueryExpression.ShaperExpression);

            shaper = InjectEntityMaterializers(shaper);

            var innerEnumerable = Visit(inMemoryQueryExpression);

            shaper = new InMemoryProjectionBindingRemovingExpressionVisitor(inMemoryQueryExpression).Visit(shaper);

            shaper = new CustomShaperCompilingExpressionVisitor(IsTracking).Visit(shaper);

            var shaperLambda = (LambdaExpression)shaper;

            return(Expression.New(
                       typeof(QueryingEnumerable <>).MakeGenericType(shaperLambda.ReturnType).GetConstructors()[0],
                       QueryCompilationContext.QueryContextParameter,
                       innerEnumerable,
                       Expression.Constant(shaperLambda.Compile()),
                       Expression.Constant(_contextType),
                       Expression.Constant(_logger)));
        }
        protected override Expression VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
        {
            Check.NotNull(shapedQueryExpression, nameof(shapedQueryExpression));

            var selectExpression = (SelectExpression)shapedQueryExpression.QueryExpression;

            selectExpression.ApplyTags(_tags);

            var dataReaderParameter        = Expression.Parameter(typeof(DbDataReader), "dataReader");
            var resultCoordinatorParameter = Expression.Parameter(typeof(ResultCoordinator), "resultCoordinator");
            var indexMapParameter          = Expression.Parameter(typeof(int[]), "indexMap");

            var shaper = new ShaperExpressionProcessingExpressionVisitor(
                selectExpression,
                dataReaderParameter,
                resultCoordinatorParameter,
                indexMapParameter)
                         .Inject(shapedQueryExpression.ShaperExpression);

            shaper = InjectEntityMaterializers(shaper);

            var isNonComposedFromSql = selectExpression.IsNonComposedFromSql();

            shaper = new RelationalProjectionBindingRemovingExpressionVisitor(
                selectExpression,
                dataReaderParameter,
                isNonComposedFromSql ? indexMapParameter : null,
                IsBuffering)
                     .Visit(shaper, out var projectionColumns);

            shaper = new CustomShaperCompilingExpressionVisitor(dataReaderParameter, resultCoordinatorParameter, IsTracking)
                     .Visit(shaper);

            IReadOnlyList <string> columnNames = null;

            if (isNonComposedFromSql)
            {
                columnNames = selectExpression.Projection.Select(pe => ((ColumnExpression)pe.Expression).Name).ToList();
            }

            var relationalCommandCache = new RelationalCommandCache(
                Dependencies.MemoryCache,
                RelationalDependencies.SqlExpressionFactory,
                RelationalDependencies.QuerySqlGeneratorFactory,
                RelationalDependencies.RelationalParameterBasedQueryTranslationPostprocessorFactory,
                _useRelationalNulls,
                selectExpression);

            var shaperLambda = (LambdaExpression)shaper;

            return(Expression.New(
                       typeof(QueryingEnumerable <>).MakeGenericType(shaperLambda.ReturnType).GetConstructors()[0],
                       Expression.Convert(QueryCompilationContext.QueryContextParameter, typeof(RelationalQueryContext)),
                       Expression.Constant(relationalCommandCache),
                       Expression.Constant(columnNames, typeof(IReadOnlyList <string>)),
                       Expression.Constant(projectionColumns, typeof(IReadOnlyList <ReaderColumn>)),
                       Expression.Constant(shaperLambda.Compile()),
                       Expression.Constant(_contextType),
                       Expression.Constant(_logger)));
        }
Beispiel #4
0
        protected override Expression VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
        {
            var inMemoryQueryExpression = (HarmonyQueryExpression)shapedQueryExpression.QueryExpression;

            //var shaper = new ShaperExpressionProcessingExpressionVisitor(
            //        inMemoryQueryExpression, inMemoryQueryExpression.CurrentParameter)
            //    .Inject(shapedQueryExpression.ShaperExpression);

            var shaper = InjectEntityMaterializers(shapedQueryExpression.ShaperExpression);

            var innerEnumerable = Visit(inMemoryQueryExpression);

            shaper = new CustomShaperCompilingExpressionVisitor(IsTracking).Visit(shaper);
            var queryExpr = shapedQueryExpression.QueryExpression as HarmonyQueryExpression;
            LambdaExpression shaperLambda = null;

            if (shaper is LambdaExpression)
            {
                shaperLambda = (LambdaExpression)shaper;
            }
            else
            {
                shaperLambda = Expression.Lambda(shaper, new ParameterExpression[] { queryExpr.CurrentParameter });
            }

            var innerEnumerableType = innerEnumerable.Type.TryGetSequenceType() ?? typeof(DataObjectBase);
            var shaperArg           = Expression.Parameter(innerEnumerableType);
            var capturedShaper      = Expression.Lambda(
                Expression.Invoke(shaperLambda,
                                  Expression.Convert(shaperArg, shaperLambda.Parameters[0].Type)),
                new ParameterExpression[] { QueryCompilationContext.QueryContextParameter, shaperArg });

            //TODO: we still need to pass the query context along here
            if (shapedQueryExpression.ResultCardinality == ResultCardinality.Single && shaperLambda.Parameters[0].Type == innerEnumerable.Type)
            {
                return(Expression.NewArrayInit(shaperLambda.ReturnType, Expression.Invoke(shaperLambda, innerEnumerable)));
            }
            else
            {
                //if trace logging is turned on, compile the shaper expression with debug info
                Delegate shaperInstance = null;
                //put this back in when its supported in .Net Core
                //if (DebugLogSession.Logging.Level == Interface.LogLevel.Trace)
                //    shaperInstance = capturedShaper.Compile(DebugInfoGenerator.CreatePdbGenerator());
                //else
                shaperInstance = capturedShaper.Compile();

                return(Expression.New(
                           typeof(QueryingEnumerable <,>).MakeGenericType(shaperLambda.ReturnType, innerEnumerableType).GetConstructors()[0],
                           QueryCompilationContext.QueryContextParameter,
                           innerEnumerable,
                           Expression.Constant(shaperInstance),
                           Expression.Constant(_contextType),
                           Expression.Constant(_logger)));
            }
        }
        protected override Expression VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
        {
            var selectExpression = (SelectExpression)shapedQueryExpression.QueryExpression;

            selectExpression.ApplyTags(_tags);

            var dataReaderParameter        = Expression.Parameter(typeof(DbDataReader), "dataReader");
            var resultCoordinatorParameter = Expression.Parameter(typeof(ResultCoordinator), "resultCoordinator");
            var indexMapParameter          = Expression.Parameter(typeof(int[]), "indexMap");

            var shaper = new ShaperExpressionProcessingExpressionVisitor(
                selectExpression,
                dataReaderParameter,
                resultCoordinatorParameter,
                indexMapParameter)
                         .Inject(shapedQueryExpression.ShaperExpression);

            shaper = InjectEntityMaterializers(shaper);

            shaper = new RelationalProjectionBindingRemovingExpressionVisitor(selectExpression, dataReaderParameter)
                     .Visit(shaper);
            shaper = new CustomShaperCompilingExpressionVisitor(
                dataReaderParameter, resultCoordinatorParameter, IsTracking)
                     .Visit(shaper);

            if (selectExpression.IsNonComposedFromSql())
            {
                shaper = new IndexMapInjectingExpressionVisitor(indexMapParameter).Visit(shaper);
            }

            var shaperLambda = (LambdaExpression)shaper;

            return(Expression.New(
                       (IsAsync
                    ? typeof(AsyncQueryingEnumerable <>)
                    : typeof(QueryingEnumerable <>)).MakeGenericType(shaperLambda.ReturnType).GetConstructors()[0],
                       Expression.Convert(QueryCompilationContext.QueryContextParameter, typeof(RelationalQueryContext)),
                       Expression.Constant(RelationalDependencies.QuerySqlGeneratorFactory),
                       Expression.Constant(RelationalDependencies.SqlExpressionFactory),
                       Expression.Constant(RelationalDependencies.ParameterNameGeneratorFactory),
                       Expression.Constant(selectExpression),
                       Expression.Constant(shaperLambda.Compile()),
                       Expression.Constant(_contextType),
                       Expression.Constant(_logger)));
        }