Пример #1
0
 protected virtual void WriteColumns(ReadOnlyCollection <DbColumnDeclaration> columns)
 {
     if (columns.Count > 0)
     {
         for (int i = 0, n = columns.Count; i < n; i++)
         {
             DbColumnDeclaration column = columns[i];
             if (i > 0)
             {
                 this.Write(", ");
             }
             DbColumnExpression c = this.VisitValue(column.Expression) as DbColumnExpression;
             if (!string.IsNullOrEmpty(column.Name) && (c == null || c.Name != column.Name))
             {
                 this.Write(" AS ");
                 this.WriteColumnName(column.Name);
             }
         }
     }
     else
     {
         this.Write("NULL ");
         if (this.isNested)
         {
             this.Write("AS ");
             this.WriteColumnName("tmp");
             this.Write(" ");
         }
     }
 }
Пример #2
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     if (this.oldAliases.Contains(column.Alias))
     {
         return new DbColumnExpression(column.Type, column.DbType, this.newAlias, column.Name);
     }
     return column;
 }
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     DbTableAlias mapped;
     if (this.map.TryGetValue(column.Alias, out mapped))
     {
         return new DbColumnExpression(column.Type, column.DbType, mapped, column.Name);
     }
     return column;
 }
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     DbColumnExpression mapped;
     if (this.map.TryGetValue(column, out mapped))
     {
         return mapped;
     }
     return column;
 }
Пример #5
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     if (column.Alias != null && !this.HideColumnAliases)
     {
         this.WriteAliasName(GetAliasName(column.Alias));
         this.Write(".");
     }
     this.WriteColumnName(column.Name);
     return(column);
 }
Пример #6
0
        /// <inheritdoc/>
        public override void Visit(DbColumnExpression e)
        {
            var columnName = e.DbColumnName.ToQuotedIdentifier();

            if (ModelAliasManager != null)
            {
                var modelAlias = ModelAliasManager[e.Column.GetParent()].ToQuotedIdentifier();
                SqlBuilder.Append(modelAlias).Append('.').Append(columnName);
            }
            else
            {
                SqlBuilder.Append(columnName);
            }
        }
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     Dictionary<string, Expression> nameMap;
     if (this.map.TryGetValue(column.Alias, out nameMap))
     {
         Expression expr;
         if (nameMap.TryGetValue(column.Name, out expr))
         {
             return this.Visit(expr);
         }
         throw new Exception("Reference to undefined column");
     }
     return column;
 }
        protected override Expression VisitSelect(DbSelectExpression select)
        {
            select = (DbSelectExpression)base.VisitSelect(select);

            // look for redundant column declarations
            List<DbColumnDeclaration> cols = select.Columns.OrderBy(c => c.Name).ToList();
            BitArray removed = new BitArray(select.Columns.Count);
            bool anyRemoved = false;
            for (int i = 0, n = cols.Count; i < n - 1; i++)
            {
                DbColumnDeclaration ci = cols[i];
                DbColumnExpression cix = ci.Expression as DbColumnExpression;
                DbDataType qt = cix != null ? cix.DbType : null;
                DbColumnExpression cxi = new DbColumnExpression(ci.Expression.Type, qt, select.Alias, ci.Name);
                for (int j = i + 1; j < n; j++)
                {
                    if (!removed.Get(j))
                    {
                        DbColumnDeclaration cj = cols[j];
                        if (SameExpression(ci.Expression, cj.Expression))
                        {
                            // any reference to 'j' should now just be a reference to 'i'
                            DbColumnExpression cxj = new DbColumnExpression(cj.Expression.Type, qt, select.Alias, cj.Name);
                            this.map.Add(cxj, cxi);
                            removed.Set(j, true);
                            anyRemoved = true;
                        }
                    }
                }
            }
            if (anyRemoved)
            {
                List<DbColumnDeclaration> newDecls = new List<DbColumnDeclaration>();
                for (int i = 0, n = cols.Count; i < n; i++)
                {
                    if (!removed.Get(i))
                    {
                        newDecls.Add(cols[i]);
                    }
                }
                select = select.SetColumns(newDecls);
            }
            return select;
        }
        private Expression MakeSubquery(Expression expression)
        {
            var newAlias = new DbTableAlias();
            var aliases = DeclaredAliasGatherer.Gather(expression);

            var decls = new List<DbColumnDeclaration>();
            foreach (var ta in aliases) 
            {
                foreach (var col in this.columns[ta])
                {
                    string name = decls.GetAvailableColumnName(col.Name);
                    var decl = new DbColumnDeclaration(name, col);
                    decls.Add(decl);
                    var newCol = new DbColumnExpression(col.Type, col.DbType, newAlias, col.Name);
                    this.map.Add(col, newCol);
                }
            }

            return new DbSelectExpression(newAlias, decls, expression, null);
        }
        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;
        }
 protected DbColumnAssignment UpdateColumnAssignment(
     DbColumnAssignment ca, DbColumnExpression c, Expression e)
 {
     if (c != ca.Column || e != ca.Expression)
         return new DbColumnAssignment(c, e);
     
     return ca;
 }
Пример #12
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     if (column.Alias != null && !this.HideColumnAliases)
     {
         this.WriteAliasName(GetAliasName(column.Alias));
         this.Write(".");
     }
     this.WriteColumnName(column.Name);
     return column;
 }
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     this.columns.Add(column);
     return column;
 }
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     MarkColumnAsUsed(column.Alias, column.Name);
     return column;
 }
Пример #15
0
 /// <summary>
 /// Visits the <see cref="DbColumnExpression"/>.
 /// </summary>
 /// <param name="expression">The expression.</param>
 /// <returns>The result.</returns>
 public abstract T Visit(DbColumnExpression expression);
 public DbColumnAssignment(
     DbColumnExpression column, Expression expression)
 {
     _column = column;
     _expression = expression;
 }
Пример #17
0
 /// <summary>
 /// Rebind order expressions to reference a new alias and add to column declarations if necessary
 /// </summary>
 protected virtual BindResult RebindOrderings(IEnumerable<DbOrderExpression> orderings, DbTableAlias alias,
     HashSet<DbTableAlias> existingAliases, IEnumerable<DbColumnDeclaration> existingColumns)
 {
     List<DbColumnDeclaration> newColumns = null;
     List<DbOrderExpression> newOrderings = new List<DbOrderExpression>();
     foreach (DbOrderExpression ordering in orderings)
     {
         Expression expr = ordering.Expression;
         DbColumnExpression column = expr as DbColumnExpression;
         if (column == null || (existingAliases != null && existingAliases.Contains(column.Alias)))
         {
             // check to see if a declared column already contains a similar expression
             int iOrdinal = 0;
             foreach (DbColumnDeclaration decl in existingColumns)
             {
                 DbColumnExpression declColumn = decl.Expression as DbColumnExpression;
                 if (decl.Expression == ordering.Expression ||
                     (column != null && declColumn != null && column.Alias == declColumn.Alias && column.Name == declColumn.Name))
                 {
                     // found it, so make a reference to this column
                     expr = new DbColumnExpression(column.Type, column.DbType, alias, decl.Name);
                     break;
                 }
                 iOrdinal++;
             }
             // if not already projected, add a new column declaration for it
             if (expr == ordering.Expression)
             {
                 if (newColumns == null)
                 {
                     newColumns = new List<DbColumnDeclaration>(existingColumns);
                     existingColumns = newColumns;
                 }
                 string colName = column != null ? column.Name : "c" + iOrdinal;
                 newColumns.Add(new DbColumnDeclaration(colName, ordering.Expression));
                 expr = new DbColumnExpression(expr.Type, null, alias, colName);
             }
             newOrderings.Add(new DbOrderExpression(ordering.OrderType, expr));
         }
     }
     return new BindResult(existingColumns, newOrderings);
 }
Пример #18
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;
     }
 }
 protected virtual bool CompareColumn(DbColumnExpression a, DbColumnExpression b)
 {
     return (CompareAlias(a.Alias, b.Alias) && a.Name == b.Name);
 }
 protected virtual Expression VisitColumn(DbColumnExpression column)
 {
     return column;
 }
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     this.aliases.Add(column.Alias);
     return column;
 }
Пример #22
0
 protected override Expression Visit(Expression expression)
 {
     if (this.candidates.Contains(expression))
     {
         if (expression.NodeType == (ExpressionType)DbExpressionType.Column)
         {
             DbColumnExpression column = (DbColumnExpression)expression;
             DbColumnExpression mapped;
             if (this.map.TryGetValue(column, out mapped))
             {
                 return mapped;
             }
             // check for column that already refers to this column
             foreach (DbColumnDeclaration existingColumn in this.columns)
             {
                 DbColumnExpression cex = existingColumn.Expression as DbColumnExpression;
                 if (cex != null && cex.Alias == column.Alias && cex.Name == column.Name)
                 {
                     // refer to the column already in the column list
                     return new DbColumnExpression(column.Type, column.DbType, this.newAlias, existingColumn.Name);
                 }
             }
             if (this.existingAliases.Contains(column.Alias)) 
             {
                 int ordinal = this.columns.Count;
                 string columnName = this.GetUniqueColumnName(column.Name);
                 this.columns.Add(new DbColumnDeclaration(columnName, column));
                 mapped = new DbColumnExpression(column.Type, column.DbType, this.newAlias, columnName);
                 this.map.Add(column, mapped);
                 this.columnNames.Add(columnName);
                 return mapped;
             }
             // must be referring to outer scope
             return column;
         }
         else
         {
             string columnName = this.GetNextColumnName();
             this.columns.Add(new DbColumnDeclaration(columnName, expression));
             return new DbColumnExpression(expression.Type, null, this.newAlias, columnName);
         }
     }
     else
     {
         return base.Visit(expression);
     }
 }