protected override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); if (select.Skip != null) { SelectExpression newSelect = select.SetSkip(null).SetTake(null); bool canAddColumn = !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0); if (!canAddColumn) { newSelect = newSelect.AddRedundantSelect(new TableAlias()); } var colType = DbTypeSystem.GetColumnType(typeof(int)); newSelect = newSelect.AddColumn(new ColumnDeclaration(columnName, new RowNumberExpression(select.OrderBy), colType)); // add layer for WHERE clause that references new rownum column newSelect = newSelect.AddRedundantSelect(new TableAlias()); newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == columnName)); var newAlias = ((SelectExpression)newSelect.From).Alias; ColumnExpression rnCol = new ColumnExpression(typeof(int), colType, newAlias, columnName); Expression where; if (select.Take != null) { where = new BetweenExpression( rnCol, Expression.Add(select.Skip, Expression.Constant(1)), Expression.Add(select.Skip, select.Take)); } else { where = rnCol.GreaterThan(select.Skip); } if (newSelect.Where != null) { where = newSelect.Where.And(where); } newSelect = newSelect.SetWhere(where); select = newSelect; } return select; }
protected override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); if (select.Skip != null) { var newSelect = select.SetSkip(null).SetTake(null).AddRedundantSelect(_language, new TableAlias()); _hasRowNumberExpression = true; var colType = _language.TypeSystem.GetColumnType(typeof(int)); newSelect = newSelect.AddColumn(new ColumnDeclaration("rownum", new RowNumberExpression(select.OrderBy), colType)); // add layer for WHERE clause that references new rownum column newSelect = newSelect.AddRedundantSelect(_language, new TableAlias()); newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == "rownum")); var newAlias = ((SelectExpression)newSelect.From).Alias; var rowNumberColumn = new ColumnExpression(typeof(int), colType, newAlias, "rownum"); Expression where; if (select.Take != null) { where = new BetweenExpression(rowNumberColumn, Expression.Add(select.Skip, Expression.Constant(1)), Expression.Add(select.Skip, select.Take)); } else { where = rowNumberColumn.GreaterThan(select.Skip); } if (newSelect.Where != null) { where = newSelect.Where.And(where); } newSelect = newSelect.SetWhere(where); select = newSelect; } return(select); }
protected override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); if (select.Skip != null) { SelectExpression newSelect = select.SetSkip(null).SetTake(null); bool canAddColumn = !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0); if (!canAddColumn) { newSelect = newSelect.AddRedundantSelect(new TableAlias()); } newSelect = newSelect.AddColumn(new ColumnDeclaration(COLUMN_NAME, new RowNumberExpression(select.OrderBy))); // add layer for WHERE clause that references new rownum column newSelect = newSelect.AddRedundantSelect(new TableAlias()); newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == COLUMN_NAME)); var newAlias = ((SelectExpression)newSelect.From).Alias; ColumnExpression rnCol = new ColumnExpression(typeof(int), newAlias, COLUMN_NAME, null); Expression where; if (select.Take != null) { where = new BetweenExpression(rnCol, Expression.Add(select.Skip, Expression.Constant(1)), Expression.Add(select.Skip, select.Take)); } else { where = rnCol.GreaterThan(select.Skip); } if (newSelect.Where != null) { where = newSelect.Where.And(where); } newSelect = newSelect.SetWhere(where); select = newSelect; } return(select); }
protected override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); if (select.Skip != null) { var newSelect = select.SetSkip(null).SetTake(null).AddRedundantSelect(_language, new TableAlias()); _hasRowNumberExpression = true; var colType = _language.TypeSystem.GetColumnType(typeof(int)); newSelect = newSelect.AddColumn(new ColumnDeclaration("rownum", new RowNumberExpression(select.OrderBy), colType)); // add layer for WHERE clause that references new rownum column newSelect = newSelect.AddRedundantSelect(_language, new TableAlias()); newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == "rownum")); var newAlias = ((SelectExpression)newSelect.From).Alias; var rowNumberColumn = new ColumnExpression(typeof(int), colType, newAlias, "rownum"); Expression where; if (select.Take != null) { where = new BetweenExpression(rowNumberColumn, Expression.Add(select.Skip, Expression.Constant(1)), Expression.Add(select.Skip, select.Take)); } else { where = rowNumberColumn.GreaterThan(select.Skip); } if (newSelect.Where != null) { where = newSelect.Where.And(where); } newSelect = newSelect.SetWhere(where); select = newSelect; } return select; }
private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot) { bool isAll = method.Name == "All"; ConstantExpression constSource = source as ConstantExpression; if (constSource != null && !IsQuery(constSource)) { System.Diagnostics.Debug.Assert(!isRoot); Expression where = null; foreach (object value in (IEnumerable)constSource.Value) { Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type)); if (where == null) { where = expr; } else if (isAll) { where = where.And(expr); } else { where = where.Or(expr); } } return this.Visit(where); } else { if (isAll) { predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray()); } if (predicate != null) { source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); } ProjectionExpression projection = this.VisitSequence(source); Expression result = new ExistsExpression(projection.Select); if (isAll) { result = Expression.Not(result); } if (isRoot) { if (this.language.AllowSubqueryInSelectWithoutFrom) { return GetSingletonSequence(result, "SingleOrDefault"); } else { // use count aggregate instead of exists var colType = this.language.TypeSystem.GetColumnType(typeof(int)); var newSelect = projection.Select.SetColumns( new[] { new ColumnDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false), colType) } ); var colx = new ColumnExpression(typeof(int), colType, newSelect.Alias, "value"); var exp = isAll ? colx.Equal(Expression.Constant(0)) : colx.GreaterThan(Expression.Constant(0)); return new ProjectionExpression( newSelect, exp, Aggregator.GetAggregator(typeof(bool), typeof(IEnumerable<bool>)) ); } } return result; } }
private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot) { bool isAll = method.Name.Equals("All", StringComparison.InvariantCultureIgnoreCase); ConstantExpression constSource = source as ConstantExpression; if (constSource != null && !IsQuery(constSource)) { System.Diagnostics.Debug.Assert(!isRoot); Expression where = null; foreach (object value in (IEnumerable)constSource.Value) { Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type)); if (where == null) { where = expr; } else if (isAll) { where = where.And(expr); } else { where = where.Or(expr); } } return(this.Visit(where)); } else { if (isAll) { predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray()); } if (predicate != null) { source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); } ProjectionExpression projection = this.VisitSequence(source); Expression result = new ExistsExpression(projection.Select); if (isAll) { result = Expression.Not(result); } if (isRoot) { if (this.language.AllowSubqueryInSelectWithoutFrom) { return(GetSingletonSequence(result, "SingleOrDefault")); } else { // use count aggregate instead of exists //var colType = this.language.TypeSystem.GetColumnType(typeof(int)); var newSelect = projection.Select.SetColumns(new[] { new ColumnDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false)) }); var colx = new ColumnExpression(typeof(int), newSelect.Alias, "value"); var exp = isAll ? colx.Equal(Expression.Constant(0)) : colx.GreaterThan(Expression.Constant(0)); return(new ProjectionExpression(newSelect, exp, Aggregator.GetAggregator(typeof(bool), typeof(IEnumerable <bool>)))); } } return(result); } }