public ProviderQueryExpression( IEnumerable<ProviderPropertyExpression> providerProperties, ProjectionExpression projection, PredicateExpression predicate, SortExpressionCollectionExpression sort) : this(new ProviderPropertiesExpression(providerProperties), projection, predicate, sort) { }
public virtual ProjectionExpression AddOuterJoinTest(ProjectionExpression proj) { var test = this.GetOuterJoinTest(proj.Select); var select = proj.Select; ColumnExpression testCol = null; // look to see if test expression exists in columns already foreach (var col in select.Columns) { if (test.Equals(col.Expression)) { var colType = SqlType.Get(test.Type); testCol = new ColumnExpression(test.Type, colType, select.Alias, col.Name); break; } } if (testCol == null) { // add expression to projection testCol = test as ColumnExpression; string colName = (testCol != null) ? testCol.Name : "Test"; colName = proj.Select.Columns.GetAvailableColumnName(colName); var colType = SqlType.Get(test.Type); select = select.AddColumn(new ColumnDeclaration(colName, test, colType)); testCol = new ColumnExpression(test.Type, colType, select.Alias, colName); } var newProjector = new OuterJoinedExpression(testCol, proj.Projector); return new ProjectionExpression(select, newProjector, proj.Aggregator); }
protected override Expression VisitProjection(ProjectionExpression proj) { if (proj != root) return AliasReplacer.Replace(base.VisitProjection(proj), aliasGenerator); else return (ProjectionExpression)base.VisitProjection(proj); }
protected override Expression VisitProjection(ProjectionExpression proj) { using (Scope()) { var oldOuterMostSelect = outerMostSelect; outerMostSelect = proj.Select; var oldHasProjectionInProjector = hasProjectionInProjector; hasProjectionInProjector = false; Expression projector = this.Visit(proj.Projector); SelectExpression source = (SelectExpression)this.Visit(proj.Select); hasProjectionInProjector = oldHasProjectionInProjector; hasProjectionInProjector |= true; outerMostSelect = oldOuterMostSelect; if (source != proj.Select || projector != proj.Projector) return new ProjectionExpression(source, projector, proj.UniqueFunction, proj.Type); return proj; } }
public ProviderQueryExpression( IEnumerable<ProviderPropertyExpression> providerProperties, ProjectionExpression projection, PredicateExpression predicate) : this(providerProperties, projection, predicate, null) { }
protected ClientJoinExpression UpdateClientJoin(ClientJoinExpression join, ProjectionExpression projection, IEnumerable<Expression> outerKey, IEnumerable<Expression> innerKey) { if (projection != join.Projection || outerKey != join.OuterKey || innerKey != join.InnerKey) { return new ClientJoinExpression(projection, outerKey, innerKey); } return join; }
public ProviderQueryExpression( ProviderPropertiesExpression providerPropertiesExpression, ProjectionExpression projection, PredicateExpression predicate) : this(providerPropertiesExpression, projection, predicate, null) { }
protected override Expression VisitProjection(ProjectionExpression proj) { Expression projector = this.Visit(proj.Projector); if (projector != proj.Projector) { return new ProjectionExpression(proj.Source, projector, proj.Aggregator); } return proj; }
protected override Expression VisitProjection(ProjectionExpression proj) { // don't parameterize the projector or aggregator! SelectExpression select = (SelectExpression)this.Visit(proj.Source); if (select != proj.Source) { return new ProjectionExpression(select, proj.Projector, proj.Aggregator); } return proj; }
public ProviderQueryExpression( ProviderPropertiesExpression providerPropertiesExpression, ProjectionExpression projection, PredicateExpression predicate, SortExpressionCollectionExpression sort) : base(projection, predicate, sort) { _providerPropertiesExpression = providerPropertiesExpression; }
protected override Expression VisitProjection(ProjectionExpression proj) { SelectExpression save = this.currentSelect; this.currentSelect = proj.Source; try { if (!this.isTopLevel) { if (this.CanJoinOnClient(this.currentSelect)) { // make a query that combines all the constraints from the outer queries into a single select SelectExpression newOuterSelect = (SelectExpression)QueryDuplicator.Duplicate(save); // remap any references to the outer select to the new alias; SelectExpression newInnerSelect = (SelectExpression)ColumnMapper.Map(proj.Source, newOuterSelect.Alias, save.Alias); // add outer-join test ProjectionExpression newInnerProjection = new ProjectionExpression(newInnerSelect, proj.Projector).AddOuterJoinTest(); newInnerSelect = newInnerProjection.Source; Expression newProjector = newInnerProjection.Projector; TableAlias newAlias = new TableAlias(); var pc = ColumnProjector.ProjectColumns(this.language.CanBeColumn, newProjector, newOuterSelect.Columns, newAlias, newOuterSelect.Alias, newInnerSelect.Alias); JoinExpression join = new JoinExpression(JoinType.OuterApply, newOuterSelect, newInnerSelect, null); SelectExpression joinedSelect = new SelectExpression(newAlias, pc.Columns, join, null, null, null, proj.IsSingleton, null, null); // apply client-join treatment recursively this.currentSelect = joinedSelect; newProjector = this.Visit(pc.Projector); // compute keys (this only works if join condition was a single column comparison) List<Expression> outerKeys = new List<Expression>(); List<Expression> innerKeys = new List<Expression>(); if (this.GetEquiJoinKeyExpressions(newInnerSelect.Where, newOuterSelect.Alias, outerKeys, innerKeys)) { // outerKey needs to refer to the outer-scope's alias var outerKey = outerKeys.Select(k => ColumnMapper.Map(k, save.Alias, newOuterSelect.Alias)); // innerKey needs to refer to the new alias for the select with the new join var innerKey = innerKeys.Select(k => ColumnMapper.Map(k, joinedSelect.Alias, ((ColumnExpression)k).Alias)); ProjectionExpression newProjection = new ProjectionExpression(joinedSelect, newProjector, proj.Aggregator); return new ClientJoinExpression(newProjection, outerKey, innerKey); } } } else { this.isTopLevel = false; } return base.VisitProjection(proj); } finally { this.currentSelect = save; } }
protected override Expression VisitProjection(ProjectionExpression proj) { proj = (ProjectionExpression)base.VisitProjection(proj); if (proj.Select.From is SelectExpression) { List<SelectExpression> redundant = RedundantSubqueryGatherer.Gather(proj.Select); if (redundant != null) { proj = SubqueryRemover.Remove(proj, redundant); } } return proj; }
static internal ProjectionExpression Flatten(ProjectionExpression proj, AliasGenerator aliasGenerator) { var result = (ProjectionExpression)new ChildProjectionFlattener { aliasGenerator = aliasGenerator }.Visit(proj); if (result == proj) return result; Expression columnCleaned = UnusedColumnRemover.Remove(result); Expression subqueryCleaned = RedundantSubqueryRemover.Remove(columnCleaned); return (ProjectionExpression)subqueryCleaned; }
protected override Expression VisitProjection(ProjectionExpression projection) { // visit mapping in reverse order Expression projector = this.Visit(projection.Projector); SelectExpression source = (SelectExpression)this.Visit(projection.Source); if (projector != projection.Projector || source != projection.Source) { return new ProjectionExpression(source, projector, projection.Aggregator); } return projection; }
private static ProjectionExpression MergeProjectionExpressions(ProjectionExpression projection, ProjectionExpression expression) { if (projection is AttributesProjectionExpression && expression is AttributesProjectionExpression) { List<PropertyNameExpression> expr = new List<PropertyNameExpression>(); expr.AddRange((projection as AttributesProjectionExpression).Attributes.Collection); expr.AddRange((expression as AttributesProjectionExpression).Attributes.Collection); return new AttributesProjectionExpression(expr); } throw GetMergeException(projection, expression); }
protected override Expression VisitProjection(ProjectionExpression proj) { this.Visit(proj.Projector); SelectExpression source = (SelectExpression)this.Visit(proj.Select); Expression projector = this.Visit(proj.Projector); if (source != proj.Select || projector != proj.Projector) { return new ProjectionExpression(source, projector, proj.UniqueFunction, proj.Type); } return proj; }
protected override Expression VisitClientJoin(ClientJoinExpression join) { // convert client join into a up-front lookup table builder & replace client-join in tree with lookup accessor // 1) lookup = query.Select(e => new KVP(key: inner, value: e)).ToLookup(kvp => kvp.Key, kvp => kvp.Value) Expression innerKey = MakeJoinKey(join.InnerKey); Expression outerKey = MakeJoinKey(join.OuterKey); ConstructorInfo kvpConstructor = typeof(KeyValuePair<,>).MakeGenericType(innerKey.Type, join.Projection.Projector.Type).GetConstructor(new System.Type[] { innerKey.Type, join.Projection.Projector.Type }); Expression constructKVPair = Expression.New(kvpConstructor, innerKey, join.Projection.Projector); ProjectionExpression newProjection = new ProjectionExpression(join.Projection.Source, constructKVPair); int iLookup = ++nLookup; Expression execution = ExecuteProjection(newProjection, false); ParameterExpression kvp = Expression.Parameter(constructKVPair.Type, "kvp"); // filter out nulls if (join.Projection.Projector.NodeType == (ExpressionType)DbExpressionType.OuterJoined) { LambdaExpression pred = Expression.Lambda( Expression.NotEqual( Expression.PropertyOrField(kvp, "Value"), Expression.Constant(null, join.Projection.Projector.Type) ), kvp ); execution = Expression.Call(typeof(Enumerable), "Where", new System.Type[] { kvp.Type }, execution, pred); } // make lookup LambdaExpression keySelector = Expression.Lambda(Expression.PropertyOrField(kvp, "Key"), kvp); LambdaExpression elementSelector = Expression.Lambda(Expression.PropertyOrField(kvp, "Value"), kvp); Expression toLookup = Expression.Call(typeof(Enumerable), "ToLookup", new System.Type[] { kvp.Type, outerKey.Type, join.Projection.Projector.Type }, execution, keySelector, elementSelector); // 2) agg(lookup[outer]) ParameterExpression lookup = Expression.Parameter(toLookup.Type, "lookup" + iLookup); PropertyInfo property = lookup.Type.GetProperty("Item"); Expression access = Expression.Call(lookup, property.GetGetMethod(), Visit(outerKey)); if (join.Projection.Aggregator != null) { // apply aggregator access = DbExpressionReplacer.Replace(join.Projection.Aggregator.Body, join.Projection.Aggregator.Parameters[0], access); } variables.Add(lookup); initializers.Add(toLookup); return access; }
protected virtual Expression VisitProjection(ProjectionExpression projection) { this.AddAlias(projection.Source.Alias); this.Write("Project("); this.WriteLine(Indentation.Inner); this.Write("@\""); this.Visit(projection.Source); this.Write("\","); this.WriteLine(Indentation.Same); this.Visit(projection.Projector); this.Write(","); this.WriteLine(Indentation.Same); this.Visit(projection.Aggregator); this.WriteLine(Indentation.Outer); this.Write(")"); return projection; }
protected override Expression VisitProjection(ProjectionExpression proj) { if (isTopLevel) { isTopLevel = false; currentSelect = proj.Source; Expression projector = Visit(proj.Projector); if (projector != proj.Projector || currentSelect != proj.Source) { return new ProjectionExpression(currentSelect, projector, proj.Aggregator); } return proj; } if (proj.IsSingleton && CanJoinOnServer(currentSelect)) { TableAlias newAlias = new TableAlias(); currentSelect = currentSelect.AddRedundantSelect(newAlias); // remap any references to the outer select to the new alias; SelectExpression source = (SelectExpression) ColumnMapper.Map(proj.Source, newAlias, currentSelect.Alias); // add outer-join test ProjectionExpression pex = new ProjectionExpression(source, proj.Projector).AddOuterJoinTest(); var pc = ColumnProjector.ProjectColumns(language.CanBeColumn, pex.Projector, currentSelect.Columns, currentSelect.Alias, newAlias, proj.Source.Alias); JoinExpression join = new JoinExpression(JoinType.OuterApply, currentSelect.From, pex.Source, null); currentSelect = new SelectExpression(currentSelect.Alias, pc.Columns, join, null); return Visit(pc.Projector); } var saveTop = isTopLevel; var saveSelect = currentSelect; isTopLevel = true; currentSelect = null; Expression result = base.VisitProjection(proj); isTopLevel = saveTop; currentSelect = saveSelect; return result; }
public override Expression Translate(Expression expression) { // fix up any order-by's expression = OrderByRewriter.Rewrite(expression); expression = base.Translate(expression); // convert skip/take info into RowNumber pattern if (isPaged(expression)) { //we have some clean up here //paging embeds a SELECT in the FROM expression //this needs to be reset to the table name //and Skip/Take need to be reset var projection = expression as ProjectionExpression; //pull the select SelectExpression outer = projection.Source; //take out the nested FROM var inner = outer.From as SelectExpression; //and stick it on the outer outer.From = inner.From; //the outer Skip is in place //reset the Take since we need both on the Select //for the formatter to work outer.Take = inner.Take; expression = new ProjectionExpression(outer, projection.Projector); } // fix up any order-by's we may have changed expression = OrderByRewriter.Rewrite(expression); return expression; }
protected abstract Expression VisitProjection(ProjectionExpression projectionExpression);
protected override Expression VisitProjection(ProjectionExpression proj) { this.Visit(proj.Projector); return(proj); }
protected override Expression VisitProjection(ProjectionExpression x) { return(x?.Update(x.Expression.VisitNode(this))); }
protected override Expression VisitProjection(ProjectionExpression projection) { return(projection); }
protected virtual Expression BindGroupBy(Expression source, LambdaExpression keySelector, LambdaExpression elementSelector, LambdaExpression resultSelector) { var projection = VisitSequence(source); _map[keySelector.Parameters[0]] = projection.Projector; var keyExpression = Visit(keySelector.Body); var elementExpression = projection.Projector; if (elementSelector != null) { _map[elementSelector.Parameters[0]] = projection.Projector; elementExpression = Visit(elementSelector.Body); } var subqueryBasis = VisitSequence(source); _map[keySelector.Parameters[0]] = subqueryBasis.Projector; var subqueryKeyExpression = Visit(keySelector.Body); var subqueryCorrelation = Expression.Equal(keyExpression, subqueryKeyExpression); var subqueryElementExpression = subqueryBasis.Projector; if (elementSelector != null) { _map[elementSelector.Parameters[0]] = subqueryBasis.Projector; subqueryElementExpression = Visit(elementSelector.Body); } var elementAlias = new Alias(); var elementProjection = _projector.ProjectFields(subqueryElementExpression, elementAlias, subqueryBasis.Source.Alias); var elementSubquery = new ProjectionExpression( new SelectExpression(elementAlias, elementProjection.Fields, subqueryBasis.Source, subqueryCorrelation), elementProjection.Projector); var alias = new Alias(); var info = new GroupByInfo(alias, elementExpression); _groupByMap[elementSubquery] = info; Expression resultExpression; if (resultSelector != null) { var saveGroupElement = _currentGroupElement; _currentGroupElement = elementSubquery; _map[resultSelector.Parameters[0]] = keyExpression; _map[resultSelector.Parameters[1]] = elementSubquery; resultExpression = Visit(resultSelector.Body); _currentGroupElement = saveGroupElement; } else { resultExpression = Expression.New( typeof(Grouping <,>).MakeGenericType(keyExpression.Type, subqueryElementExpression.Type).GetConstructors()[0], new[] { keyExpression, elementSubquery }); } var fieldProjection = _projector.ProjectFields(resultExpression, alias, projection.Source.Alias); var projectedElementSubquery = ((NewExpression)fieldProjection.Projector).Arguments[1]; _groupByMap[projectedElementSubquery] = info; return(new ProjectionExpression( new SelectExpression(alias, new FieldDeclaration[0], projection.Source, null, null, keyExpression, false, null, null), fieldProjection.Projector)); }
private Expression BindAggregate(Expression source, MethodInfo method, LambdaExpression argument, bool isRoot) { Type returnType = method.ReturnType; AggregateType aggType = GetAggregateType(method.Name); bool hasPredicateArg = HasPredicateArg(aggType); bool isDistinct = false; bool argumentWasPredicate = false; bool useAlternateArg = false; // check for distinct MethodCallExpression mcs = source as MethodCallExpression; if (mcs != null && !hasPredicateArg && argument == null) { if (mcs.Method.Name == "Distinct" && mcs.Arguments.Count == 1 && (mcs.Method.DeclaringType == typeof(Queryable) || mcs.Method.DeclaringType == typeof(Enumerable))) { source = mcs.Arguments[0]; isDistinct = true; } } if (argument != null && hasPredicateArg) { // convert query.Count(predicate) into query.Where(predicate).Count() source = Expression.Call(typeof(Queryable), "Where", method.GetGenericArguments(), source, argument); argument = null; argumentWasPredicate = true; } ProjectionExpression projection = VisitSequence(source); Expression argExpr = null; if (argument != null) { map[argument.Parameters[0]] = projection.Projector; argExpr = Visit(argument.Body); } else if (!hasPredicateArg || useAlternateArg) { argExpr = projection.Projector; } var alias = GetNextAlias(); var pc = ProjectColumns(projection.Projector, alias, projection.Source.Alias); Expression aggExpr = new AggregateExpression(returnType, aggType, argExpr, isDistinct); SelectExpression select = new SelectExpression(alias, new[] { new ColumnDeclaration("", aggExpr) }, projection.Source, null); if (isRoot) { ParameterExpression p = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(aggExpr.Type), "p"); LambdaExpression gator = Expression.Lambda(Expression.Call(typeof(Enumerable), "Single", new[] { returnType }, p), p); return(new ProjectionExpression(select, new ColumnExpression(returnType, alias, ""), gator)); } ScalarExpression subquery = new ScalarExpression(returnType, select); // if we can find the corresponding group-info we can build a special AggregateSubquery node that will enable us to // optimize the aggregate expression later using AggregateRewriter GroupByInfo info; if (!argumentWasPredicate && groupByMap.TryGetValue(projection, out info)) { // use the element expression from the group-by info to rebind the argument so the resulting expression is one that // would be legal to add to the columns in the select expression that has the corresponding group-by clause. if (argument != null) { map[argument.Parameters[0]] = info.Element; argExpr = Visit(argument.Body); } else if (!hasPredicateArg || useAlternateArg) { argExpr = info.Element; } aggExpr = new AggregateExpression(returnType, aggType, argExpr, isDistinct); // check for easy to optimize case. If the projection that our aggregate is based on is really the 'group' argument from // the query.GroupBy(xxx, (key, group) => yyy) method then whatever expression we return here will automatically // become part of the select expression that has the group-by clause, so just return the simple aggregate expression. if (projection == currentGroupElement) { return(aggExpr); } return(new AggregateSubqueryExpression(info.Alias, aggExpr, subquery)); } return(subquery); }
public Expression VisitProjection(ProjectionExpression proj) { return(_defaultVisitor.Visit(proj)); }
protected virtual bool CompareProjection(ProjectionExpression a, ProjectionExpression b) { if (!this.Compare(a.Select, b.Select)) return false; var save = this.aliasScope; try { this.aliasScope = new ScopedDictionary<TableAlias, TableAlias>(this.aliasScope); this.aliasScope.Add(a.Select.Alias, b.Select.Alias); return this.Compare(a.Projector, b.Projector) && this.Compare(a.Aggregator, b.Aggregator) && a.IsSingleton == b.IsSingleton; } finally { this.aliasScope = save; } }
public override Expression GetMemberExpression(Expression root, MappingEntity entity, MemberInfo member) { if (this.mapping.IsAssociationRelationship(entity, member)) { MappingEntity relatedEntity = this.mapping.GetRelatedEntity(entity, member); ProjectionExpression projection = this.GetQueryExpression(relatedEntity); // make where clause for joining back to 'root' var declaredTypeMembers = this.mapping.GetAssociationKeyMembers(entity, member).ToList(); var associatedMembers = this.mapping.GetAssociationRelatedKeyMembers(entity, member).ToList(); Expression where = null; for (int i = 0, n = associatedMembers.Count; i < n; i++) { Expression equal = this.GetMemberExpression(projection.Projector, relatedEntity, associatedMembers[i]).Equal( this.GetMemberExpression(root, entity, declaredTypeMembers[i]) ); where = (where != null) ? where.And(equal) : equal; } TableAlias newAlias = new TableAlias(); var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, projection.Projector, null, newAlias, projection.Select.Alias); LambdaExpression aggregator = Aggregator.GetAggregator(TypeHelper.GetMemberType(member), typeof(IEnumerable<>).MakeGenericType(pc.Projector.Type)); var result = new ProjectionExpression( new SelectExpression(newAlias, pc.Columns, projection.Select, where), pc.Projector, aggregator ); return this.translator.Police.ApplyPolicy(result, member); } else { AliasedExpression aliasedRoot = root as AliasedExpression; if (aliasedRoot != null && this.mapping.IsColumn(entity, member)) { return new ColumnExpression(TypeHelper.GetMemberType(member), this.GetColumnType(entity, member), aliasedRoot.Alias, this.mapping.GetColumnName(entity, member)); } return QueryBinder.BindMember(root, member); } }
protected override Expression VisitProjection(ProjectionExpression projection) { // visit mapping in reverse order Expression projector = this.Visit(projection.Projector); SelectExpression select = (SelectExpression)this.Visit(projection.Select); return this.UpdateProjection(projection, select, projector, projection.Aggregator); }
public FeatureQueryExpression(ProjectionExpression projection, PredicateExpression predicate, SortExpressionCollectionExpression sort) : base(projection, predicate, sort) { }
public ISourceInjectedQueryable <TDestination> For <TDestination>(params Expression <Func <TDestination, object> >[] membersToExpand) { _membersToExpand = ProjectionExpression.GetMemberPaths(membersToExpand); return(CreateQueryable <TDestination>()); }
private TranslatedQuery PrepareSubqueryParameters(SubQueryExpression subQueryExpression, out Parameter <Tuple> parameterOfTuple, out Type elementType, out ProjectionExpression projection) { // 1. Rewrite recordset and ItemProjector to parameter<tuple> var subqueryTupleParameter = context.GetTupleParameter(subQueryExpression.OuterParameter); var newDataSource = ApplyParameterToTupleParameterRewriter.Rewrite( subQueryExpression.ProjectionExpression.ItemProjector.DataSource, subqueryTupleParameter, subQueryExpression.ApplyParameter); var newItemProjectorBody = ApplyParameterToTupleParameterRewriter.Rewrite( subQueryExpression.ProjectionExpression.ItemProjector.Item, subqueryTupleParameter, subQueryExpression.ApplyParameter); var itemProjector = new ItemProjectorExpression(newItemProjectorBody, newDataSource, subQueryExpression.ProjectionExpression.ItemProjector.Context); parameterOfTuple = context.GetTupleParameter(subQueryExpression.OuterParameter); // 2. Add only parameter<tuple>. Tuple value will be assigned // at the moment of materialization in SubQuery constructor projection = new ProjectionExpression( subQueryExpression.ProjectionExpression.Type, itemProjector, subQueryExpression.ProjectionExpression.TupleParameterBindings, subQueryExpression.ProjectionExpression.ResultAccessMethod); // 3. Make translation elementType = subQueryExpression.ProjectionExpression.ItemProjector.Item.Type; var translateMethod = Translator.TranslateMethod; return((TranslatedQuery)translateMethod.Invoke( context.Translator, new object[] { projection, tupleParameters.Append(parameterOfTuple) })); }
protected internal override Expression VisitProjection(ProjectionExpression proj) { throw new InvalidOperationException("No ProjectionExpressions expected at this stage"); }
protected override Expression VisitProjection(ProjectionExpression proj) { var projector = Visit(proj.Projector); return(proj.Update(proj.Select, projector, proj.Aggregator)); }
internal static ITranslateResult Build(ProjectionExpression proj) { Type type = proj.UniqueFunction == null?proj.Type.ElementType() !: proj.Type; return(miBuildPrivate.GetInvoker(type)(proj)); }
internal static Expression BindMember(Expression source, MemberInfo member) { switch (source.NodeType) { case ExpressionType.MemberInit: MemberInitExpression min = (MemberInitExpression)source; for (int i = 0, n = min.Bindings.Count; i < n; i++) { MemberAssignment assign = min.Bindings[i] as MemberAssignment; if (assign != null && MembersMatch(assign.Member, member)) { return(assign.Expression); } } break; case ExpressionType.New: NewExpression nex = (NewExpression)source; if (nex.Members != null) { for (int i = 0, n = nex.Members.Count; i < n; i++) { if (MembersMatch(nex.Members[i], member)) { return(nex.Arguments[i]); } } } else if (nex.Type.IsGenericType && nex.Type.GetGenericTypeDefinition() == typeof(Grouping <,>)) { if (member.Name == "Key") { return(nex.Arguments[0]); } } break; case (ExpressionType)DbExpressionType.Projection: // member access on a projection turns into a new projection w/ member access applied ProjectionExpression proj = (ProjectionExpression)source; Expression newProjector = BindMember(proj.Projector, member); return(new ProjectionExpression(proj.Source, newProjector)); case (ExpressionType)DbExpressionType.OuterJoined: OuterJoinedExpression oj = (OuterJoinedExpression)source; Expression em = BindMember(oj.Expression, member); if (em is ColumnExpression) { return(em); } return(new OuterJoinedExpression(oj.Test, em)); case ExpressionType.Conditional: ConditionalExpression cex = (ConditionalExpression)source; return(Expression.Condition(cex.Test, BindMember(cex.IfTrue, member), BindMember(cex.IfFalse, member))); case ExpressionType.Constant: ConstantExpression con = (ConstantExpression)source; if (con.Value == null) { Type memberType = TypeHelper.GetMemberType(member); return(Expression.Constant(GetDefault(memberType), memberType)); } break; } return(Expression.MakeMemberAccess(source, member)); }
protected override Expression VisitProjection(ProjectionExpression proj) { // treat these like scalar subqueries if ((proj.Projector is ColumnExpression) || this.forDebug) { this.Write("("); this.WriteLine(Indentation.Inner); this.Visit(proj.Select); this.Write(")"); this.Indent(Indentation.Outer); } else { throw new NotSupportedException("Non-scalar projections cannot be translated to SQL."); } return proj; }
protected virtual Expression BindGroupBy(Expression source, LambdaExpression keySelector, LambdaExpression elementSelector, LambdaExpression resultSelector) { ProjectionExpression projection = VisitSequence(source); map[keySelector.Parameters[0]] = projection.Projector; Expression keyExpr = Visit(keySelector.Body); Expression elemExpr = projection.Projector; if (elementSelector != null) { map[elementSelector.Parameters[0]] = projection.Projector; elemExpr = Visit(elementSelector.Body); } // Use ProjectColumns to get group-by expressions from key expression ProjectedColumns keyProjection = ProjectColumns(keyExpr, projection.Source.Alias, projection.Source.Alias); IEnumerable <Expression> groupExprs = keyProjection.Columns.Select(c => c.Expression); // make duplicate of source query as basis of element subquery by visiting the source again ProjectionExpression subqueryBasis = VisitSequence(source); // recompute key columns for group expressions relative to subquery (need these for doing the correlation predicate) map[keySelector.Parameters[0]] = subqueryBasis.Projector; Expression subqueryKey = Visit(keySelector.Body); // use same projection trick to get group-by expressions based on subquery ProjectedColumns subqueryKeyPC = ProjectColumns(subqueryKey, subqueryBasis.Source.Alias, subqueryBasis.Source.Alias); IEnumerable <Expression> subqueryGroupExprs = subqueryKeyPC.Columns.Select(c => c.Expression); Expression subqueryCorrelation = BuildPredicateWithNullsEqual(subqueryGroupExprs, groupExprs); // compute element based on duplicated subquery Expression subqueryElemExpr = subqueryBasis.Projector; if (elementSelector != null) { map[elementSelector.Parameters[0]] = subqueryBasis.Projector; subqueryElemExpr = Visit(elementSelector.Body); } // build subquery that projects the desired element var elementAlias = GetNextAlias(); ProjectedColumns elementPC = ProjectColumns(subqueryElemExpr, elementAlias, subqueryBasis.Source.Alias); ProjectionExpression elementSubquery = new ProjectionExpression( new SelectExpression(elementAlias, elementPC.Columns, subqueryBasis.Source, subqueryCorrelation), elementPC.Projector ); var alias = GetNextAlias(); // make it possible to tie aggregates back to this group-by GroupByInfo info = new GroupByInfo(alias, elemExpr); groupByMap.Add(elementSubquery, info); Expression resultExpr; if (resultSelector != null) { Expression saveGroupElement = currentGroupElement; currentGroupElement = elementSubquery; // compute result expression based on key and element-subquery map[resultSelector.Parameters[0]] = keyProjection.Projector; map[resultSelector.Parameters[1]] = elementSubquery; resultExpr = Visit(resultSelector.Body); currentGroupElement = saveGroupElement; } else { // result must be IGrouping<K,E> resultExpr = Expression.New( typeof(Grouping <,>).MakeGenericType(keyExpr.Type, subqueryElemExpr.Type).GetConstructors()[0], new[] { keyExpr, elementSubquery } ); } ProjectedColumns pc = ProjectColumns(resultExpr, alias, projection.Source.Alias); // make it possible to tie aggregates back to this group-by Expression projectedElementSubquery = ((NewExpression)pc.Projector).Arguments[1]; groupByMap.Add(projectedElementSubquery, info); return(new ProjectionExpression( new SelectExpression(alias, pc.Columns, projection.Source, null, null, groupExprs), pc.Projector )); }
public Grouping(ProjectionExpression projectionExpression, TranslatedQuery translatedQuery, Parameter <Tuple> parameter, Tuple tuple, TKey key, ItemMaterializationContext context) : base(projectionExpression, translatedQuery, parameter, tuple, context) { Key = key; }
protected virtual Expression VisitProjectionExpression(ProjectionExpression projectionExpression) { return(projectionExpression); }
protected override Expression VisitProjection(ProjectionExpression proj) { SelectExpression select = (SelectExpression)this.Visit(proj.Select); return(this.UpdateProjection(proj, select, proj.Projector, proj.Aggregator)); }
public virtual Expression GetInsertResult(IEntityMapping mapping, Expression instance, LambdaExpression selector, Dictionary <MemberInfo, Expression> map) { var tableAlias = new TableAlias(); var tex = new TableExpression(tableAlias, mapping); var aggregator = Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable <>).MakeGenericType(selector.Body.Type)); Expression where = null; DeclarationCommand genIdCommand = null; var generatedIds = mapping.PrimaryKeys.Where(m => m.IsPrimaryKey && m.IsGenerated).ToList(); if (generatedIds.Count > 0) { if (map == null || !generatedIds.Any(m => map.ContainsKey(m.Member))) { var localMap = new Dictionary <MemberInfo, Expression>(); genIdCommand = this.GetGeneratedIdCommand(mapping, generatedIds, localMap); map = localMap; } // is this just a retrieval of one generated id member? var mex = selector.Body as MemberExpression; if (mex != null) { var id = mapping.Get(mex.Member); if (id != null && id.IsPrimaryKey && id.IsGenerated) { if (genIdCommand != null) { // just use the select from the genIdCommand return(new ProjectionExpression( genIdCommand.Source, new ColumnExpression(mex.Type, genIdCommand.Variables[0].SqlType, genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name), aggregator )); } else { TableAlias alias = new TableAlias(); var colType = id.SqlType; return(new ProjectionExpression( new SelectExpression(alias, new[] { new ColumnDeclaration("", map[mex.Member], colType) }, null, null), new ColumnExpression(mex.Member.GetMemberType(), colType, alias, ""), aggregator )); } } where = generatedIds.Select((m, i) => this.GetMemberExpression(tex, mapping, m.Member).Equal(map[m.Member]) ).Aggregate((x, y) => x.And(y)); } } else { where = this.GetIdentityCheck(tex, mapping, instance); } Expression typeProjector = this.GetEntityExpression(tex, mapping); Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector); TableAlias newAlias = new TableAlias(); var pc = ColumnProjector.ProjectColumns(selection, null, newAlias, tableAlias); var pe = new ProjectionExpression( new SelectExpression(newAlias, pc.Columns, tex, where), pc.Projector, aggregator ); if (genIdCommand != null) { return(new BlockCommand(genIdCommand, pe)); } return(pe); }
protected override Expression VisitProjection(ProjectionExpression proj) { this.found = proj; return(proj); }
public ISourceInjectedQueryable <TDestination> For <TDestination>(IObjectDictionary parameters, params string[] membersToExpand) { _parameters = parameters; _membersToExpand = ProjectionExpression.GetMemberPaths(typeof(TDestination), membersToExpand); return(CreateQueryable <TDestination>()); }
protected override Expression VisitProjection(ProjectionExpression projection) { Visit(projection.Source); return(projection); }
private Expression BindFirst(Expression source, LambdaExpression predicate, string kind, bool isRoot) { ProjectionExpression projection = this.VisitSequence(source); Expression where = null; if (predicate != null) { this.map[predicate.Parameters[0]] = projection.Projector; where = this.Visit(predicate.Body); } bool isFirst = kind.StartsWith("First"); bool isLast = kind.StartsWith("Last"); Expression take = (isFirst || isLast) ? Expression.Constant(1) : null; if (take != null || where != null) { var alias = this.GetNextAlias(); ProjectedColumns pc = this.ProjectColumns(projection.Projector, alias, projection.Select.Alias); projection = new ProjectionExpression( new SelectExpression(alias, pc.Columns, projection.Select, where, null, null, false, null, take, isLast), pc.Projector ); } if (isRoot) { Type elementType = projection.Projector.Type; ParameterExpression p = Expression.Parameter(typeof(IEnumerable<>).MakeGenericType(elementType), "p"); LambdaExpression gator = Expression.Lambda(Expression.Call(typeof(Enumerable), kind, new Type[] { elementType }, p), p); return new ProjectionExpression(projection.Select, projection.Projector, gator); } return projection; }
protected abstract Expression VisitProjection([NotNull] ProjectionExpression projectionExpression);
public override ProjectionExpression GetQueryExpression(MappingEntity entity) { var tableAlias = new TableAlias(); var selectAlias = new TableAlias(); var table = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity)); Expression projector = this.GetEntityExpression(table, entity); var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, projector, null, selectAlias, tableAlias); var proj = new ProjectionExpression( new SelectExpression(selectAlias, pc.Columns, table, null), pc.Projector ); return (ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType); }
private static bool IsNullableProjection(ProjectionExpression projection) { return(projection.Expression is ColumnExpression column ? column.Nullable : true); }
protected virtual Expression GetInsertResult(MappingEntity entity, Expression instance, LambdaExpression selector, Dictionary<MemberInfo, Expression> map) { var tableAlias = new TableAlias(); var tex = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity)); var aggregator = Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable<>).MakeGenericType(selector.Body.Type)); Expression where; DeclarationCommand genIdCommand = null; var generatedIds = this.mapping.GetMappedMembers(entity).Where(m => this.mapping.IsPrimaryKey(entity, m) && this.mapping.IsGenerated(entity, m)).ToList(); if (generatedIds.Count > 0) { if (map == null || !generatedIds.Any(m => map.ContainsKey(m))) { var localMap = new Dictionary<MemberInfo, Expression>(); genIdCommand = this.GetGeneratedIdCommand(entity, generatedIds.ToList(), localMap); map = localMap; } // is this just a retrieval of one generated id member? var mex = selector.Body as MemberExpression; if (mex != null && this.mapping.IsPrimaryKey(entity, mex.Member) && this.mapping.IsGenerated(entity, mex.Member)) { if (genIdCommand != null) { // just use the select from the genIdCommand return new ProjectionExpression( genIdCommand.Source, new ColumnExpression(mex.Type, genIdCommand.Variables[0].QueryType, genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name), aggregator ); } else { TableAlias alias = new TableAlias(); var colType = this.GetColumnType(entity, mex.Member); return new ProjectionExpression( new SelectExpression(alias, new[] { new ColumnDeclaration("", map[mex.Member], colType) }, null, null), new ColumnExpression(TypeHelper.GetMemberType(mex.Member), colType, alias, ""), aggregator ); } } where = generatedIds.Select((m, i) => this.GetMemberExpression(tex, entity, m).Equal(map[m]) ).Aggregate((x, y) => x.And(y)); } else { where = this.GetIdentityCheck(tex, entity, instance); } Expression typeProjector = this.GetEntityExpression(tex, entity); Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector); TableAlias newAlias = new TableAlias(); var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, selection, null, newAlias, tableAlias); var pe = new ProjectionExpression( new SelectExpression(newAlias, pc.Columns, tex, where), pc.Projector, aggregator ); if (genIdCommand != null) { return new BlockCommand(genIdCommand, pe); } return pe; }
public TResult Execute <TResult>(Expression expression) { try { var resultType = typeof(TResult); Inspector.StartQueryExecuteInterceptor(resultType, expression); var sourceExpression = ConvertDestinationExpressionToSourceExpression(expression); var destResultType = typeof(TResult); var sourceResultType = CreateSourceResultType(destResultType); object destResult = null; // case #1: query is a projection from complex Source to complex Destination // example: users.UseAsDataSource().For<UserDto>().Where(x => x.Age > 20).ToList() if (IsProjection <TDestination>(resultType)) { // in case of a projection, we need an IQueryable var sourceResult = _dataSource.Provider.CreateQuery(sourceExpression); Inspector.SourceResult(sourceExpression, sourceResult); destResult = new ProjectionExpression((IQueryable <TSource>)sourceResult, _mapper.ConfigurationProvider.ExpressionBuilder).To <TDestination>(_parameters, _membersToExpand); } // case #2: query is arbitrary ("manual") projection // exaple: users.UseAsDataSource().For<UserDto>().Select(user => user.Age).ToList() // in case an arbitrary select-statement is enumerated, we do not need to map the expression at all // and cann safely return it else if (IsProjection(resultType, sourceExpression)) { var sourceResult = _dataSource.Provider.CreateQuery(sourceExpression); var enumerator = sourceResult.GetEnumerator(); var elementType = ElementTypeHelper.GetElementType(typeof(TResult)); var constructorInfo = typeof(List <>).MakeGenericType(elementType).GetDeclaredConstructor(new Type[0]); if (constructorInfo != null) { var listInstance = (IList)constructorInfo.Invoke(null); while (enumerator.MoveNext()) { listInstance.Add(enumerator.Current); } destResult = listInstance; } } // case #2: projection to simple type // example: users.UseAsDataSource().For<UserDto>().FirstOrDefault(user => user.Age > 20) else { /* * in case of an element result (so instead of IQueryable<TResult>, just TResult) * we still want to support parameters. * This is e.g. the case, when the developer writes "UseAsDataSource().For<TResult>().FirstOrDefault(x => ...) * To still be able to support parameters, we need to create a query from it. * That said, we need to replace the "element" operator "FirstOrDefault" with a "Where" operator, then apply our "Select" * to map from TSource to TResult and finally re-apply the "element" operator ("FirstOrDefault" in our case) so only * one element is returned by our "Execute<TResult>" method. Otherwise we'd get an InvalidCastException * * So first we visit the sourceExpression and replace "element operators" with "where" * then we create our mapping expression from TSource to TDestination (select) and apply it * finally, we search for the element expression overload of our replaced "element operator" that has no expression as parameter * this expression is not needed anymore as it has already been applied to the "Where" operation and can be safely omitted * when we're done creating our new expression, we call the underlying provider to execute it */ // as we need to replace the innermost element of the expression, // we need to traverse it first in order to find the node to replace or potential caveats // e.g. .UseAsDataSource().For<Dto>().Select(e => e.Name).First() // in the above case we cannot map anymore as the "select" operator overrides our mapping. var searcher = new ReplaceableMethodNodeFinder <TSource>(); searcher.Visit(sourceExpression); // provide the replacer with our found MethodNode or <null> var replacer = new MethodNodeReplacer <TSource>(searcher.MethodNode); // default back to simple mapping of object instance for backwards compatibility (e.g. mapping non-nullable to nullable fields) sourceExpression = replacer.Visit(sourceExpression); if (replacer.FoundElementOperator) { /* in case of primitive element operators (e.g. Any(), Sum()...) * we need to map the originating types (e.g. Entity to Dto) in this query * as the final value will be projected automatically * * == example 1 == * UseAsDataSource().For<Dto>().Any(entity => entity.Name == "thename") * ..in that case sourceResultType and destResultType would both be "Boolean" which is not mappable for AutoMapper * * == example 2 == * UseAsDataSource().For<Dto>().FirstOrDefault(entity => entity.Name == "thename") * ..in this case the sourceResultType would be Entity and the destResultType Dto, so we can map the query directly */ if (sourceResultType == destResultType)// && destResultType.IsPrimitive) { sourceResultType = typeof(TSource); destResultType = typeof(TDestination); } var membersToExpand = _membersToExpand.SelectMany(m => m).Distinct().ToArray(); var lambdas = _mapper.ConfigurationProvider.ExpressionBuilder.GetMapExpression(sourceResultType, destResultType, _parameters, membersToExpand); // add projection via "select" operator var expr = lambdas.Aggregate(sourceExpression, (source, lambda) => Select(source, lambda)); // in case an element operator without predicate expression was found (and thus not replaced) var replacementMethod = replacer.ElementOperator; // in case an element operator with predicate expression was replaced if (replacer.ReplacedMethod != null) { // find replacement method that has no more predicates replacementMethod = typeof(Queryable).GetAllMethods() .Single(m => m.Name == replacer.ReplacedMethod.Name #if NET45 && m.GetParameters().All(p => typeof(Queryable).IsAssignableFrom(p.Member.ReflectedType)) #endif && m.GetParameters().Length == replacer.ReplacedMethod.GetParameters().Length - 1); } // reintroduce element operator that was replaced with a "where" operator to make it queryable expr = Expression.Call(null, replacementMethod.MakeGenericMethod(destResultType), expr); destResult = _dataSource.Provider.Execute(expr); } // If there was no element operator that needed to be replaced by "where", just map the result else { var sourceResult = _dataSource.Provider.Execute(sourceExpression); Inspector.SourceResult(sourceExpression, sourceResult); destResult = _mapper.Map(sourceResult, sourceResultType, destResultType); } } Inspector.DestResult(destResult); // implicitly convert types in case of valuetypes which cannot be casted explicitly if (typeof(TResult).IsValueType() && destResult?.GetType() != typeof(TResult)) { return((TResult)Convert.ChangeType(destResult, typeof(TResult))); } // if it is not a valuetype, we can safely cast it return((TResult)destResult); } catch (Exception x) { _exceptionHandler(x); throw; } }
protected virtual Expression VisitProjection(ProjectionExpression proj) { SelectExpression source = (SelectExpression)this.Visit(proj.Source); Expression projector = this.Visit(proj.Projector); if (source != proj.Source || projector != proj.Projector) { return new ProjectionExpression(source, projector, proj.Aggregator); } return proj; }
public static ProjectionExpression Remove(ProjectionExpression projection, params SelectExpression[] selectsToRemove) { return(Remove(projection, (IEnumerable <SelectExpression>)selectsToRemove)); }
protected override Expression VisitProjection(ProjectionExpression proj) { if (currentSource == null) { currentSource = WithoutOrder(proj.Select); Expression projector = this.Visit(proj.Projector); if (projector != proj.Projector) proj = new ProjectionExpression(proj.Select, projector, proj.UniqueFunction, proj.Type); currentSource = null; return proj; } else { HashSet<ColumnExpression> columns = ExternalColumnGatherer.Gatherer(proj, currentSource.Alias); if (columns.Count == 0) { Expression projector = Visit(proj.Projector); ConstantExpression key = Expression.Constant(0); Type kvpType = typeof(KeyValuePair<,>).MakeGenericType(key.Type, projector.Type); ConstructorInfo ciKVP = kvpType.GetConstructor(new[] { key.Type, projector.Type }); Type projType = proj.UniqueFunction == null ? typeof(IEnumerable<>).MakeGenericType(kvpType) : kvpType; var childProj = new ProjectionExpression(proj.Select, Expression.New(ciKVP, key, projector), proj.UniqueFunction, projType); return new ChildProjectionExpression(childProj, Expression.Constant(0), inMList, proj.Type, new LookupToken()); } else { SelectExpression external; IEnumerable<ColumnExpression> externalColumns; if (!IsKey(currentSource, columns)) { Alias aliasDistinct = aliasGenerator.GetUniqueAlias(currentSource.Alias.Name + "D"); ColumnGenerator generatorDistinct = new ColumnGenerator(); List<ColumnDeclaration> columnDistinct = columns.Select(ce => generatorDistinct.MapColumn(ce)).ToList(); external = new SelectExpression(aliasDistinct, true, null, columnDistinct, currentSource, null, null, null, 0); Dictionary<ColumnExpression, ColumnExpression> distinctReplacements = columnDistinct.ToDictionary( cd => (ColumnExpression)cd.Expression, cd => cd.GetReference(aliasDistinct)); proj = (ProjectionExpression)ColumnReplacer.Replace(proj, distinctReplacements); externalColumns = distinctReplacements.Values.ToHashSet(); } else { external = currentSource; externalColumns = columns; } ColumnGenerator generatorSM = new ColumnGenerator(); List<ColumnDeclaration> columnsSMExternal = externalColumns.Select(ce => generatorSM.MapColumn(ce)).ToList(); List<ColumnDeclaration> columnsSMInternal = proj.Select.Columns.Select(cd => generatorSM.MapColumn(cd.GetReference(proj.Select.Alias))).ToList(); List<OrderExpression> innerOrders; SelectExpression @internal = ExtractOrders(proj.Select, out innerOrders); Alias aliasSM = aliasGenerator.GetUniqueAlias(@internal.Alias.Name + "SM"); SelectExpression selectMany = new SelectExpression(aliasSM, false, null, columnsSMExternal.Concat(columnsSMInternal), new JoinExpression(JoinType.CrossApply, external, @internal, null), null, innerOrders, null, 0); SelectExpression old = currentSource; currentSource = WithoutOrder(selectMany); var selectManyReplacements = selectMany.Columns.ToDictionary( cd => (ColumnExpression)cd.Expression, cd => cd.GetReference(aliasSM)); Expression projector = ColumnReplacer.Replace(proj.Projector, selectManyReplacements); projector = Visit(projector); currentSource = old; Expression key = TupleReflection.TupleChainConstructor(columnsSMExternal.Select(cd => cd.GetReference(aliasSM).Nullify())); Type kvpType = typeof(KeyValuePair<,>).MakeGenericType(key.Type, projector.Type); ConstructorInfo ciKVP = kvpType.GetConstructor(new[] { key.Type, projector.Type }); Type projType = proj.UniqueFunction == null ? typeof(IEnumerable<>).MakeGenericType(kvpType) : kvpType; var childProj = new ProjectionExpression(selectMany, Expression.New(ciKVP, key, projector), proj.UniqueFunction, projType); return new ChildProjectionExpression(childProj, TupleReflection.TupleChainConstructor(columns.Select(a => a.Nullify())), inMList, proj.Type, new LookupToken()); } } }
public static ProjectionExpression Remove(ProjectionExpression projection, IEnumerable <SelectExpression> selectsToRemove) { return((ProjectionExpression) new SubqueryRemover(selectsToRemove).Visit(projection)); }
public override ProjectionExpression GetQueryExpression(MappingEntity entity) { var tables = this.mapping.GetTables(entity); if (tables.Count <= 1) { return base.GetQueryExpression(entity); } var aliases = new Dictionary<string, TableAlias>(); MappingTable rootTable = tables.Single(ta => !this.mapping.IsExtensionTable(ta)); var tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(rootTable)); aliases.Add(this.mapping.GetAlias(rootTable), tex.Alias); Expression source = tex; foreach (MappingTable table in tables.Where(t => this.mapping.IsExtensionTable(t))) { TableAlias joinedTableAlias = new TableAlias(); string extensionAlias = this.mapping.GetAlias(table); aliases.Add(extensionAlias, joinedTableAlias); List<string> keyColumns = this.mapping.GetExtensionKeyColumnNames(table).ToList(); List<MemberInfo> relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToList(); string relatedAlias = this.mapping.GetExtensionRelatedAlias(table); TableAlias relatedTableAlias; aliases.TryGetValue(relatedAlias, out relatedTableAlias); TableExpression joinedTex = new TableExpression(joinedTableAlias, entity, this.mapping.GetTableName(table)); Expression cond = null; for (int i = 0, n = keyColumns.Count; i < n; i++) { var memberType = TypeHelper.GetMemberType(relatedMembers[i]); var colType = this.GetColumnType(entity, relatedMembers[i]); var relatedColumn = new ColumnExpression(memberType, colType, relatedTableAlias, this.mapping.GetColumnName(entity, relatedMembers[i])); var joinedColumn = new ColumnExpression(memberType, colType, joinedTableAlias, keyColumns[i]); var eq = joinedColumn.Equal(relatedColumn); cond = (cond != null) ? cond.And(eq) : eq; } source = new JoinExpression(JoinType.SingletonLeftOuter, source, joinedTex, cond); } var columns = new List<ColumnDeclaration>(); this.GetColumns(entity, aliases, columns); SelectExpression root = new SelectExpression(new TableAlias(), columns, source, null); var existingAliases = aliases.Values.ToArray(); Expression projector = this.GetEntityExpression(root, entity); var selectAlias = new TableAlias(); var pc = ColumnProjector.ProjectColumns(this.Translator.Linguist.Language, projector, null, selectAlias, root.Alias); var proj = new ProjectionExpression( new SelectExpression(selectAlias, pc.Columns, root, null), pc.Projector ); return (ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType); }
protected override Expression VisitProjection(ProjectionExpression projectionExpression) { var expression = (SqlExpression)Visit(projectionExpression.Expression); return(projectionExpression.Update(expression)); }
protected virtual Expression BuildExecuteBatch(BatchExpression batch) { Expression operation = this.Parameterize(batch.Operation.Body); var cdu = batch.Operation.Body as CDUCommandExpression; Type entityType = null; if (cdu != null) { entityType = cdu.Table.Mapping.EntityType; } string commandText = this.dbContext.BuildSql(operation); var namedValues = NamedValueGatherer.Gather(operation); var parameters = namedValues.Select(v => new NamedParameter(v.Name, v.Type, v.SqlType)).ToArray(); Expression[] values = namedValues.Select(v => Expression.Convert(this.Visit(v.Value), typeof(object))).ToArray(); Expression paramSets = Expression.Call(typeof(Enumerable), "Select", new Type[] { batch.Operation.Parameters[1].Type, typeof(object[]) }, batch.Input, Expression.Lambda(Expression.NewArrayInit(typeof(object), values), new[] { batch.Operation.Parameters[1] }) ); Expression plan = null; ProjectionExpression projection = ProjectionFinder.FindProjection(operation); if (projection != null) { var saveScope = this.scope; ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++); this.scope = new Scope(this.scope, reader, projection.Select.Alias, projection.Select.Columns); LambdaExpression projector = Expression.Lambda(this.Visit(projection.Projector), reader); this.scope = saveScope; // var entity = EntityFinder.Find(projection.Projector); var batchContext = Expression.New(typeof(BatchContext <>).MakeGenericType(projector.Body.Type).GetConstructors().FirstOrDefault(), Expression.Constant(commandText), Expression.Constant(parameters), paramSets, projector); plan = Expression.Call(this.executor, "Batch", new Type[] { projector.Body.Type }, batchContext); } else { var batchContext = Expression.New(typeof(BatchContext).GetConstructors().FirstOrDefault(), Expression.Constant(commandText), Expression.Constant(parameters), paramSets, Expression.Constant(entityType)); //plan = Expression.Call(this.executor, "Batch", null, // Expression.Constant(commandText), // Expression.Constant(parameters), // paramSets // ); plan = Expression.Call(this.executor, "Batch", null, batchContext); } return(plan); }
private static bool IsNullableProjection(ProjectionExpression projection) => !(projection.Expression is ColumnExpression column) || column.IsNullable;