Beispiel #1
0
        protected override Expression VisitSelect(DbSelectExpression select)
        {
            select = (DbSelectExpression)base.VisitSelect(select);
            if (select.Skip != null)
            {
                DbSelectExpression newSelect = select.SetSkip(null).SetTake(null);
                bool canAddColumn            = !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0);
                if (!canAddColumn)
                {
                    newSelect = newSelect.AddRedundantSelect(new DbTableAlias());
                }
                newSelect = newSelect.AddColumn(new DbColumnDeclaration("rownum", new DbRowNumberExpression(select.OrderBy)));

                // add layer for WHERE clause that references new rownum column
                newSelect = newSelect.AddRedundantSelect(new DbTableAlias());
                newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == "rownum"));

                var newAlias             = ((DbSelectExpression)newSelect.From).Alias;
                DbColumnExpression rnCol = new DbColumnExpression(typeof(int), null, newAlias, "rownum");
                Expression where;
                if (select.Take != null)
                {
                    where = new DbBetweenExpression(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);
        }
Beispiel #2
0
        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(Queryable), "Where", method.GetGenericArguments(), source, predicate);
                }
                DbProjectionExpression projection = this.VisitSequence(source);
                Expression             result     = new DbExistsExpression(projection.Select);
                if (isAll)
                {
                    result = Expression.Not(result);
                }
                if (isRoot)
                {
                    if (this.mapping.Language.AllowSubqueryInSelectWithoutFrom)
                    {
                        return(GetSingletonSequence(result, "SingleOrDefault"));
                    }
                    else
                    {
                        // use count aggregate instead of exists
                        var newSelect = projection.Select.SetColumns(
                            new[] { new DbColumnDeclaration("value", new DbAggregateExpression(typeof(int), DbAggregateType.Count, null, false)) }
                            );
                        var colx = new DbColumnExpression(typeof(int), null, newSelect.Alias, "value");
                        var exp  = isAll
                            ? colx.Equal(Expression.Constant(0))
                            : colx.GreaterThan(Expression.Constant(0));
                        return(new DbProjectionExpression(
                                   newSelect, exp, Aggregator.Aggregate(typeof(bool), typeof(IEnumerable <bool>))
                                   ));
                    }
                }
                return(result);
            }
        }