/// <summary> /// Helper method for <see cref="TransformIntersectOrExcept(DbExpression left, DbExpression right, DbExpressionKind expressionKind, IList<DbPropertyExpression> sortExpressionsOverLeft, string sortExpressionsBindingVariableName)"/> /// 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> /// <param name="inputBinding"></param> /// <param name="flattenedProperties"></param> /// <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; }
internal DbExpression Project(DbExpressionBinding input, DbExpression projection) { var lifter = GetLifter(input.Expression); return lifter.Project(input.Project(projection)); }