internal ColumnExpression(ProjectionExpression subqueryProjection, TableExpressionBase table, bool nullable) : this(subqueryProjection.Alias, table, subqueryProjection.Type, subqueryProjection.Expression.TypeMapping, nullable) { }
public void PushdownIntoSubQuery() { var subquery = Clone("t"); if (subquery.Limit == null && subquery.Offset == null) { subquery.ClearOrdering(); } _projectionMapping.Clear(); var columnNameCounter = 0; var index = 0; var result = new Dictionary <ProjectionMember, Expression>(); foreach (var projection in subquery._projectionMapping) { result[projection.Key] = Constant(index); if (projection.Value is EntityProjectionExpression entityProjection) { var propertyExpressions = new Dictionary <IProperty, ColumnExpression>(); foreach (var property in entityProjection.EntityType.GetProperties()) { var innerColumn = entityProjection.GetProperty(property); var projectionExpression = new ProjectionExpression(innerColumn, innerColumn.Name); subquery._projection.Add(projectionExpression); propertyExpressions[property] = new ColumnExpression(projectionExpression, subquery, innerColumn.Nullable); index++; } _projectionMapping[projection.Key] = new EntityProjectionExpression( entityProjection.EntityType, propertyExpressions); } else { var projectionExpression = new ProjectionExpression( (SqlExpression)projection.Value, "c" + columnNameCounter++); subquery._projection.Add(projectionExpression); _projectionMapping[projection.Key] = new ColumnExpression( projectionExpression, subquery, IsNullableProjection(projectionExpression)); index++; } } subquery._projectionMapping = result; var currentOrderings = _orderings.ToList(); _orderings.Clear(); foreach (var ordering in currentOrderings) { var orderingExpression = ordering.Expression; var innerProjection = subquery._projection.FirstOrDefault( pe => pe.Expression.Equals(orderingExpression)); if (innerProjection != null) { _orderings.Add(new OrderingExpression(new ColumnExpression(innerProjection, subquery, IsNullableProjection(innerProjection)), ordering.Ascending)); } else { var projectionExpression = new ProjectionExpression(ordering.Expression, "c" + columnNameCounter++); subquery._projection.Add(projectionExpression); _orderings.Add(new OrderingExpression( new ColumnExpression(projectionExpression, subquery, IsNullableProjection(projectionExpression)), ordering.Ascending)); } } Offset = null; Limit = null; IsDistinct = false; Predicate = null; _tables.Clear(); _tables.Add(subquery); }
private static bool IsNullableProjection(ProjectionExpression projection) { return(projection.Expression is ColumnExpression column ? column.Nullable : true); }
private static bool IsNullableProjection(ProjectionExpression projectionExpression) => projectionExpression.Expression switch {