private DbExpression RewriteCollection(DbExpression expression)
        {
            DbExpression        dbExpression      = expression;
            DbProjectExpression projectExpression = (DbProjectExpression)null;

            if (DbExpressionKind.Project == expression.ExpressionKind)
            {
                projectExpression = (DbProjectExpression)expression;
                dbExpression      = projectExpression.Input.Expression;
            }
            ObjectSpanRewriter.NavigationInfo navInfo = (ObjectSpanRewriter.NavigationInfo)null;
            if (this.RelationshipSpan)
            {
                dbExpression = ObjectSpanRewriter.RelationshipNavigationVisitor.FindNavigationExpression(dbExpression, this._aliasGenerator, out navInfo);
            }
            if (navInfo != null)
            {
                this.EnterNavigationCollection(navInfo);
            }
            else
            {
                this.EnterCollection();
            }
            DbExpression body = expression;

            if (projectExpression != null)
            {
                DbExpression projection = this.Rewrite(projectExpression.Projection);
                if (!object.ReferenceEquals((object)projectExpression.Projection, (object)projection))
                {
                    body = (DbExpression)dbExpression.BindAs(projectExpression.Input.VariableName).Project(projection);
                }
            }
            else
            {
                DbExpressionBinding input      = dbExpression.BindAs(this._aliasGenerator.Next());
                DbExpression        variable   = (DbExpression)input.Variable;
                DbExpression        projection = this.Rewrite(variable);
                if (!object.ReferenceEquals((object)variable, (object)projection))
                {
                    body = (DbExpression)input.Project(projection);
                }
            }
            this.ExitCollection();
            if (navInfo != null && navInfo.InUse)
            {
                body = (DbExpression)DbExpressionBuilder.Lambda(body, (IEnumerable <DbVariableReferenceExpression>) new List <DbVariableReferenceExpression>(1)
                {
                    navInfo.SourceVariable
                }).Invoke((IEnumerable <DbExpression>) new List <DbExpression>(1)
                {
                    navInfo.Source
                });
            }
            return(body);
        }
Beispiel #2
0
                internal virtual DbExpression OfType(TypeUsage type)
                {
                    // s.OfType<T> is normally translated to s.Filter(e => e is T).Project(e => e as T)
                    DbExpressionBinding rootBinding   = _root.BindAs(_aliasGenerator.Next());
                    DbExpression        filter        = this.Filter(rootBinding.Filter(rootBinding.Variable.IsOf(type)));
                    OrderByLifterBase   filterLifter  = GetLifter(filter, _aliasGenerator);
                    DbExpressionBinding filterBinding = filter.BindAs(_aliasGenerator.Next());
                    DbExpression        project       = filterLifter.Project(filterBinding.Project(filterBinding.Variable.TreatAs(type)));

                    return(project);
                }
        // <summary>
        // Helper method for
        // <see
        //     cref="TransformIntersectOrExcept(DbExpression, DbExpression, DbExpressionKind, System.Collections.Generic.IList{System.Data.Entity.Core.Common.CommandTrees.DbPropertyExpression}, string)" />
        // Creates a
        // <see cref="DbProjectExpression" />
        // over the given inputBinding that projects out the given flattenedProperties.
        // and updates the flattenedProperties to be over the newly created project.
        // </summary>
        // <returns>
        // An <see cref="DbExpressionBinding" /> over the newly created <see cref="DbProjectExpression" />
        // </returns>
        private static DbExpressionBinding CapWithProject(DbExpressionBinding inputBinding, IList <DbPropertyExpression> flattenedProperties)
        {
            var projectColumns = new List <KeyValuePair <string, DbExpression> >(flattenedProperties.Count);

            //List of all the columnNames used in the projection.
            var columnNames = new Dictionary <string, int>(flattenedProperties.Count);

            foreach (var pe in flattenedProperties)
            {
                //There may be conflicting property names, thus we may need to rename.
                var name = pe.Property.Name;
                int i;
                if (columnNames.TryGetValue(name, out i))
                {
                    string newName;
                    do
                    {
                        ++i;
                        newName = name + i.ToString(CultureInfo.InvariantCulture);
                    }while (columnNames.ContainsKey(newName));

                    columnNames[name] = i;
                    name = newName;
                }

                // Add this column name to list of known names so that there are no subsequent
                // collisions
                columnNames[name] = 0;
                projectColumns.Add(new KeyValuePair <string, DbExpression>(name, pe));
            }

            //Build the project
            DbExpression rowExpr           = DbExpressionBuilder.NewRow(projectColumns);
            var          projectExpression = inputBinding.Project(rowExpr);

            //Create the new inputBinding
            var resultBinding = projectExpression.Bind();

            //Create the list of flattenedProperties over the new project
            flattenedProperties.Clear();
            var rowExprType = (RowType)rowExpr.ResultType.EdmType;

            foreach (var column in projectColumns)
            {
                var prop = rowExprType.Properties[column.Key];
                flattenedProperties.Add(resultBinding.Variable.Property(prop));
            }
            return(resultBinding);
        }
Beispiel #4
0
        private DbExpression GenerateStructuralTypeResultMappingView(
            DbExpression storeFunctionInvoke,
            out DiscriminatorMap discriminatorMap)
        {
            discriminatorMap = (DiscriminatorMap)null;
            DbExpression dbExpression = storeFunctionInvoke;
            DbExpression queryView;

            if (this.m_structuralTypeMappings.Count == 1)
            {
                Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > structuralTypeMapping = this.m_structuralTypeMappings[0];
                StructuralType structuralType = structuralTypeMapping.Item1;
                List <ConditionPropertyMapping> conditions       = structuralTypeMapping.Item2;
                List <PropertyMapping>          propertyMappings = structuralTypeMapping.Item3;
                if (conditions.Count > 0)
                {
                    dbExpression = (DbExpression)dbExpression.Where((Func <DbExpression, DbExpression>)(row => FunctionImportMappingComposable.GenerateStructuralTypeConditionsPredicate(conditions, row)));
                }
                DbExpressionBinding input = dbExpression.BindAs("row");
                DbExpression        structuralTypeMappingView = FunctionImportMappingComposable.GenerateStructuralTypeMappingView(structuralType, propertyMappings, (DbExpression)input.Variable);
                queryView = (DbExpression)input.Project(structuralTypeMappingView);
            }
            else
            {
                DbExpressionBinding binding = dbExpression.BindAs("row");
                List <DbExpression> list    = this.m_structuralTypeMappings.Select <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> >, DbExpression>((Func <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> >, DbExpression>)(m => FunctionImportMappingComposable.GenerateStructuralTypeConditionsPredicate(m.Item2, (DbExpression)binding.Variable))).ToList <DbExpression>();
                binding = binding.Filter(Helpers.BuildBalancedTreeInPlace <DbExpression>((IList <DbExpression>)list.ToArray(), (Func <DbExpression, DbExpression, DbExpression>)((prev, next) => (DbExpression)prev.Or(next)))).BindAs("row");
                List <DbExpression> source = new List <DbExpression>(this.m_structuralTypeMappings.Count);
                foreach (Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > structuralTypeMapping in this.m_structuralTypeMappings)
                {
                    StructuralType         structuralType   = structuralTypeMapping.Item1;
                    List <PropertyMapping> propertyMappings = structuralTypeMapping.Item3;
                    source.Add(FunctionImportMappingComposable.GenerateStructuralTypeMappingView(structuralType, propertyMappings, (DbExpression)binding.Variable));
                }
                DbExpression projection = (DbExpression)DbExpressionBuilder.Case(list.Take <DbExpression>(this.m_structuralTypeMappings.Count - 1), source.Take <DbExpression>(this.m_structuralTypeMappings.Count - 1), source[this.m_structuralTypeMappings.Count - 1]);
                queryView = (DbExpression)binding.Project(projection);
                DiscriminatorMap.TryCreateDiscriminatorMap(this.FunctionImport.EntitySet, queryView, out discriminatorMap);
            }
            return(queryView);
        }
        private static DbExpressionBinding CapWithProject(
            DbExpressionBinding inputBinding,
            IList <DbPropertyExpression> flattenedProperties)
        {
            List <KeyValuePair <string, DbExpression> > keyValuePairList = new List <KeyValuePair <string, DbExpression> >(flattenedProperties.Count);
            Dictionary <string, int> dictionary = new Dictionary <string, int>(flattenedProperties.Count);

            foreach (DbPropertyExpression flattenedProperty in (IEnumerable <DbPropertyExpression>)flattenedProperties)
            {
                string key1 = flattenedProperty.Property.Name;
                int    num;
                if (dictionary.TryGetValue(key1, out num))
                {
                    string key2;
                    do
                    {
                        ++num;
                        key2 = key1 + num.ToString((IFormatProvider)CultureInfo.InvariantCulture);
                    }while (dictionary.ContainsKey(key2));
                    dictionary[key1] = num;
                    key1             = key2;
                }
                dictionary[key1] = 0;
                keyValuePairList.Add(new KeyValuePair <string, DbExpression>(key1, (DbExpression)flattenedProperty));
            }
            DbExpression        projection        = (DbExpression)DbExpressionBuilder.NewRow((IEnumerable <KeyValuePair <string, DbExpression> >)keyValuePairList);
            DbExpressionBinding expressionBinding = inputBinding.Project(projection).Bind();

            flattenedProperties.Clear();
            RowType edmType = (RowType)projection.ResultType.EdmType;

            foreach (KeyValuePair <string, DbExpression> keyValuePair in keyValuePairList)
            {
                EdmProperty property = edmType.Properties[keyValuePair.Key];
                flattenedProperties.Add(expressionBinding.Variable.Property(property));
            }
            return(expressionBinding);
        }
Beispiel #6
0
        private DbExpression RewriteCollection(DbExpression expression, CollectionType collectionType)
        {
            DbExpression target = expression;

            // If the collection expression is a project expression, get a strongly typed reference to it for later use.
            DbProjectExpression project = null;

            if (DbExpressionKind.Project == expression.ExpressionKind)
            {
                project = (DbProjectExpression)expression;
                target  = project.Input.Expression;
            }

            // If Relationship span is enabled and the source of this collection is (directly or indirectly)
            // a RelationshipNavigation operation, it may be possible to optimize the relationship span rewrite
            // for the Entities produced by the navigation.
            NavigationInfo navInfo = null;

            if (this.RelationshipSpan)
            {
                // Attempt to find a RelationshipNavigationExpression in the collection-defining expression
                target = RelationshipNavigationVisitor.FindNavigationExpression(target, _aliasGenerator, out navInfo);
            }

            // If a relationship navigation expression defines this collection, make the Ref that is the navigation source
            // and the source association end available for possible use when the projection over the collection is rewritten.
            if (navInfo != null)
            {
                this.EnterNavigationCollection(navInfo);
            }
            else
            {
                // Otherwise, add a null navigation info instance to the stack to indicate that relationship navigation
                // cannot be optimized for the entities produced by this collection expression (if it is a collection of entities).
                this.EnterCollection();
            }

            // If the expression is already a DbProjectExpression then simply visit the projection,
            // instead of introducing another projection over the existing one.
            DbExpression result = expression;

            if (project != null)
            {
                DbExpression newProjection = this.Rewrite(project.Projection);
                if (!object.ReferenceEquals(project.Projection, newProjection))
                {
                    result = target.BindAs(project.Input.VariableName).Project(newProjection);
                }
            }
            else
            {
                // This is not a recognized special case, so simply add the span projection over the original
                // collection-producing expression, if it is required.
                DbExpressionBinding collectionBinding = target.BindAs(_aliasGenerator.Next());
                DbExpression        projection        = collectionBinding.Variable;

                DbExpression spannedProjection = this.Rewrite(projection);

                if (!object.ReferenceEquals(projection, spannedProjection))
                {
                    result = collectionBinding.Project(spannedProjection);
                }
            }

            // Remove any navigation information from scope, if it was added
            this.ExitCollection();

            // If a navigation expression defines this collection and its navigation information was used to
            // short-circuit relationship span rewrites, then enclose the entire rewritten expression in a
            // Lambda binding that brings the source Ref of the navigation operation into scope. This ref is
            // refered to by VariableReferenceExpressions in the original navigation expression as well as any
            // short-circuited relationship span columns in the rewritten expression.
            if (navInfo != null && navInfo.InUse)
            {
                // Create a Lambda function that binds the original navigation source expression under the variable name
                // used in the navigation expression and the relationship span columns, and which has its Lambda body
                // defined by the rewritten collection expression.
                List <DbVariableReferenceExpression> formals = new List <DbVariableReferenceExpression>(1);
                formals.Add(navInfo.SourceVariable);

                List <DbExpression> args = new List <DbExpression>(1);
                args.Add(navInfo.Source);

                result = DbExpressionBuilder.Invoke(DbExpressionBuilder.Lambda(result, formals), args);
            }

            // Return the (possibly rewritten) collection expression.
            return(result);
        }
Beispiel #7
0
            internal DbExpression Project(DbExpressionBinding input, DbExpression projection)
            {
                OrderByLifterBase lifter = GetLifter(input.Expression);

                return(lifter.Project(input.Project(projection)));
            }
Beispiel #8
0
                protected DbProjectExpression RebindProject(DbExpression input, DbProjectExpression project)
                {
                    DbExpressionBinding inputBinding = input.BindAs(project.Input.VariableName);

                    return(inputBinding.Project(project.Projection));
                }