public virtual ProjectionExpression AddOuterJoinTest(ProjectionExpression proj) { Expression test = GetOuterJoinTest(proj.Select); SelectExpression select = proj.Select; ColumnExpression testCol = null; // look to see if test expression exists in columns already foreach (ColumnDeclaration col in select.Columns) { if (test.Equals(col.Expression)) { QueryType colType = TypeSystem.GetColumnType(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); QueryType colType = TypeSystem.GetColumnType(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 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(language, new TableAlias()); } QueryType 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")); TableAlias newAlias = ((SelectExpression)newSelect.From).Alias; var rnCol = new ColumnExpression(typeof(int), colType, newAlias, "_rownum"); 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); }