Example #1
0
        // <summary>
        // Collapses outerProject(outerProjection(innerProject(innerNew)))
        // </summary>
        private static DbExpression CollapseNestedProjection(DbExpression expression)
        {
            var outerProject    = (DbProjectExpression)expression;
            var outerProjection = outerProject.Projection;
            var innerProject    = (DbProjectExpression)outerProject.Input.Expression;
            var innerNew        = (DbNewInstanceExpression)innerProject.Projection;

            // get membername -> expression bindings for the inner select so that we know how map property
            // references to the inner projection
            var bindings             = new Dictionary <string, DbExpression>(innerNew.Arguments.Count);
            var innerResultTypeUsage = innerNew.ResultType;
            var innerResultType      = (RowType)innerResultTypeUsage.EdmType;

            for (var ordinal = 0; ordinal < innerResultType.Members.Count; ordinal++)
            {
                bindings[innerResultType.Members[ordinal].Name] = innerNew.Arguments[ordinal];
            }

            // initialize an expression visitor that knows how to map arguments to the outer projection
            // to the inner projection source
            var collapser = new ProjectionCollapser(bindings, outerProject.Input);

            // replace all property references to the inner projection
            var replacementOuterProjection = collapser.CollapseProjection(outerProjection);

            // make sure the collapsing was successful; if not, give up on simplification
            if (collapser.IsDoomed)
            {
                return(null);
            }

            // set replacement value so that the expression replacer infrastructure can substitute
            // the collapsed projection in the expression tree
            // continue collapsing projection until the pattern no longer matches
            var replacementOuterProject = innerProject.Input.Project(replacementOuterProjection);

            return(replacementOuterProject);
        }
        /// <summary>
        /// Collapses outerProject(outerProjection(innerProject(innerNew)))
        /// </summary>
        private static DbExpression CollapseNestedProjection(DbExpression expression)
        {
            DbProjectExpression outerProject = (DbProjectExpression)expression;
            DbExpression outerProjection = outerProject.Projection;
            DbProjectExpression innerProject = (DbProjectExpression)outerProject.Input.Expression;
            DbNewInstanceExpression innerNew = (DbNewInstanceExpression)innerProject.Projection;

            // get membername -> expression bindings for the inner select so that we know how map property
            // references to the inner projection
            Dictionary<string, DbExpression> bindings = new Dictionary<string, DbExpression>(innerNew.Arguments.Count);
            TypeUsage innerResultTypeUsage = innerNew.ResultType;
            RowType innerResultType = (RowType)innerResultTypeUsage.EdmType;

            for (int ordinal = 0; ordinal < innerResultType.Members.Count; ordinal++)
            {
                bindings[innerResultType.Members[ordinal].Name] = innerNew.Arguments[ordinal];
            }

            // initialize an expression visitor that knows how to map arguments to the outer projection
            // to the inner projection source
            ProjectionCollapser collapser = new ProjectionCollapser(bindings, outerProject.Input);

            // replace all property references to the inner projection
            var replacementOuterProjection = collapser.CollapseProjection(outerProjection);
            
            // make sure the collapsing was successful; if not, give up on simplification
            if (collapser.IsDoomed) { return null; }
            
            // set replacement value so that the expression replacer infrastructure can substitute
            // the collapsed projection in the expression tree
            // continue collapsing projection until the pattern no longer matches
            DbProjectExpression replacementOuterProject = innerProject.Input.Project(replacementOuterProjection);
            return replacementOuterProject;
        }