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); }
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); }
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); }
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); }
internal DbExpression Project(DbExpressionBinding input, DbExpression projection) { OrderByLifterBase lifter = GetLifter(input.Expression); return(lifter.Project(input.Project(projection))); }
protected DbProjectExpression RebindProject(DbExpression input, DbProjectExpression project) { DbExpressionBinding inputBinding = input.BindAs(project.Input.VariableName); return(inputBinding.Project(project.Projection)); }