private bool CanJoinOnClient(DbSelectExpression select) { return ( this.canJoinOnClient && this.currentMember != null && !this.policy.IsDeferLoaded(this.currentMember) && !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0) && !DbAggregateChecker.HasAggregates(select) ); }
private bool CanJoinOnServer(DbSelectExpression select) { return(select.IsDistinct == false && (select.GroupBy == null || select.GroupBy.Count == 0) && !DbAggregateChecker.HasAggregates(select)); }
protected override Expression VisitJoin(DbJoinExpression join) { join = base.VisitJoin(join) as DbJoinExpression; if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply) { if (join.Right is DbTableExpression) { return(new DbJoinExpression(JoinType.CrossJoin, join.Left, join.Right, null)); } if (join.Right is DbSelectExpression select && select.Take == null && select.Skip == null && !DbAggregateChecker.HasAggregates(select) && (select.GroupBy == null || select.GroupBy.Count == 0)) { var selectWithoutWhere = select.SetWhere(null); var referencedAliases = DbReferencedAliasGatherer.Gather(selectWithoutWhere); var declaredAliases = DbDeclaredAliasGatherer.Gather(join.Left); if (referencedAliases != null) { referencedAliases.IntersectWith(declaredAliases); } if (referencedAliases.Count == 0) { var where = select.Where; select = selectWithoutWhere; var pc = DbColumnProjector.ProjectColumns(this.language, where, select.Columns, select.Alias, DbDeclaredAliasGatherer.Gather(select.From)); select = select.SetColumns(pc.Columns); where = pc.Projector; var jt = (where == null) ? JoinType.CrossJoin : (join.JoinType == JoinType.CrossApply ? JoinType.InnerJoin : JoinType.LeftOuter); return(new DbJoinExpression(jt, join.Left, select, where)); } } } return(join); }
protected override Expression VisitSelect(DbSelectExpression select) { bool saveIsOuterMostSelect = this.isOuterMostSelect; try { this.isOuterMostSelect = false; select = base.VisitSelect(select) as DbSelectExpression; var hasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0; var hasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0; var canHaveOrderBy = saveIsOuterMostSelect || select.Take != null || select.Skip != null; var canReceiveOrderings = canHaveOrderBy && !hasGroupBy && !select.IsDistinct && !DbAggregateChecker.HasAggregates(select); if (hasOrderBy) { this.PrependOrderings(select.OrderBy); } if (select.IsReverse) { this.ReverseOrderings(); } var orderings = null as IEnumerable <DbOrderExpression>; if (canReceiveOrderings) { orderings = this.gatheredOrderings; } else if (canHaveOrderBy) { orderings = select.OrderBy; } var canPassOnOrderings = !saveIsOuterMostSelect && !hasGroupBy && !select.IsDistinct; var columns = select.Columns; if (this.gatheredOrderings != null) { if (canPassOnOrderings) { var producedAliases = DbDeclaredAliasGatherer.Gather(select.From); var project = this.RebindOrderings(this.gatheredOrderings, select.Alias, producedAliases, select.Columns); this.gatheredOrderings = null; this.PrependOrderings(project.Orderings); columns = project.Columns; } else { this.gatheredOrderings = null; } } if (orderings != select.OrderBy || columns != select.Columns || select.IsReverse) { select = new DbSelectExpression(select.Alias, columns, select.From, select.Where, orderings, select.GroupBy, select.IsDistinct, select.Skip, select.Take, false); } return(select); } finally { this.isOuterMostSelect = saveIsOuterMostSelect; } }
private static bool CanMergeWithFrom(DbSelectExpression select, bool isTopLevel) { var fromSelect = GetLeftMostSelect(select.From); if (fromSelect == null) { return(false); } if (IsColumnProjection(fromSelect) == false) { return(false); } var selHasNameMapProjection = IsNameMapProjection(select); var selHasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0; var selHasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0; var selHasAggregates = DbAggregateChecker.HasAggregates(select); var selHasJoin = select.From is DbJoinExpression; var frmHasOrderBy = fromSelect.OrderBy != null && fromSelect.OrderBy.Count > 0; var frmHasGroupBy = fromSelect.GroupBy != null && fromSelect.GroupBy.Count > 0; var frmHasAggregates = DbAggregateChecker.HasAggregates(fromSelect); if (selHasOrderBy && frmHasOrderBy) { return(false); } if (selHasGroupBy && frmHasGroupBy) { return(false); } if (select.IsReverse || fromSelect.IsReverse) { return(false); } if (frmHasOrderBy && (selHasGroupBy || selHasAggregates || select.IsDistinct)) { return(false); } if (frmHasGroupBy) { return(false); } if (fromSelect.Take != null && (select.Take != null || select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin)) { return(false); } if (fromSelect.Skip != null && (select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin)) { return(false); } if (fromSelect.IsDistinct && (select.Take != null || select.Skip != null || !selHasNameMapProjection || selHasGroupBy || selHasAggregates || (selHasOrderBy && !isTopLevel) || selHasJoin)) { return(false); } if (frmHasAggregates && (select.Take != null || select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin)) { return(false); } return(true); }