protected override Expression VisitSelect(SelectExpression select) { // select * from table order by x skip s take t // => // select * from (select top s * from (select top s + t from table order by x) order by -x) order by x select = (SelectExpression)base.VisitSelect(select); if (select.Skip != null && select.Take != null && select.OrderBy.Count > 0) { var skip = select.Skip; var take = select.Take; var skipPlusTake = PartialEvaluator.Eval(Expression.Add(skip, take)); select = select.SetTake(skipPlusTake).SetSkip(null); select = select.AddRedundantSelect(this.language, new TableAlias()); select = select.SetTake(take); // propogate order-bys to new layer select = (SelectExpression)OrderByRewriter.Rewrite(this.language, select); var inverted = select.OrderBy.Select(ob => new OrderExpression( ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression )); select = select.SetOrderBy(inverted); select = select.AddRedundantSelect(this.language, new TableAlias()); select = select.SetTake(Expression.Constant(0)); // temporary select = (SelectExpression)OrderByRewriter.Rewrite(this.language, select); var reverted = select.OrderBy.Select(ob => new OrderExpression( ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression )); select = select.SetOrderBy(reverted); select = select.SetTake(null); } return(select); }
public override Expression ApplyPolicy(Expression expression, MemberInfo member) { List <LambdaExpression> ops; if (this.policy.operations.TryGetValue(member, out ops)) { var result = expression; foreach (var fnOp in ops) { var pop = PartialEvaluator.Eval(fnOp, this.Translator.Mapper.Mapping.CanBeEvaluatedLocally); result = this.Translator.Mapper.ApplyMapping(Expression.Invoke(pop, result)); } var projection = (ProjectionExpression)result; if (projection.Type != expression.Type) { var fnAgg = Aggregator.GetAggregator(expression.Type, projection.Type); projection = new ProjectionExpression(projection.Select, projection.Projector, fnAgg); } return(projection); } return(expression); }
internal IQueryProvider FindProvider(Expression expression, object[] args) { Expression root = this.FindProviderInExpression(expression) as ConstantExpression; if (root == null && args != null && args.Length > 0) { Expression replaced = ExpressionReplacer.ReplaceAll( expression, this.query.Parameters.ToArray(), args.Select((a, i) => Expression.Constant(a, this.query.Parameters[i].Type)).ToArray() ); root = this.FindProviderInExpression(replaced); } if (root != null) { ConstantExpression cex = root as ConstantExpression; if (cex == null) { cex = PartialEvaluator.Eval(root) as ConstantExpression; } if (cex != null) { IQueryProvider provider = cex.Value as IQueryProvider; if (provider == null) { IQueryable query = cex.Value as IQueryable; if (query != null) { provider = query.Provider; } } return(provider); } } return(null); }