public void AddJoin(AdditionalFromClause join) { AdditionalJoins.Add(join); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { _queryParts.AddFromPart(fromClause); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause( AdditionalFromClause fromClause, QueryModel queryModel, int index) { Check.NotNull(fromClause, nameof(fromClause)); Check.NotNull(queryModel, nameof(queryModel)); base.VisitAdditionalFromClause(fromClause, queryModel, index); RequiresClientSelectMany = true; var selectExpression = TryGetQuery(fromClause); if (selectExpression != null && selectExpression.Tables.Count == 1) { var previousQuerySource = FindPreviousQuerySource(queryModel, index); if (previousQuerySource != null && !RequiresClientJoin) { var previousSelectExpression = TryGetQuery(previousQuerySource); if (previousSelectExpression != null) { if (!QueryCompilationContext.QuerySourceRequiresMaterialization(previousQuerySource)) { previousSelectExpression.ClearProjection(); previousSelectExpression.IsProjectStar = false; } var readerOffset = previousSelectExpression.Projection.Count; var correlated = selectExpression.IsCorrelated(); if (correlated) { if (!QueryCompilationContext.IsLateralJoinSupported) { return; } previousSelectExpression .AddLateralJoin(selectExpression.Tables.First(), selectExpression.Projection); } else { previousSelectExpression .AddCrossJoin(selectExpression.Tables.First(), selectExpression.Projection); } QueriesBySource.Remove(fromClause); Expression = _queryFlattenerFactory .Create( fromClause, QueryCompilationContext, LinqOperatorProvider.SelectMany, readerOffset) .Flatten((MethodCallExpression)Expression); RequiresClientSelectMany = false; } } } if (RequiresClientSelectMany) { CheckClientEval(fromClause); } }
private Expression RewriteNavigationsIntoJoins( QuerySourceReferenceExpression outerQuerySourceReferenceExpression, IEnumerable <INavigation> navigations, PropertyInfo member) { var querySourceReferenceExpression = outerQuerySourceReferenceExpression; var navigationJoins = _navigationJoins; var optionalNavigationInChain = false; foreach (var navigation in navigations) { if (!navigation.ForeignKey.IsRequired) { optionalNavigationInChain = true; } var targetEntityType = navigation.GetTargetType(); if (navigation.IsCollection()) { _queryModel.MainFromClause.FromExpression = CreateEntityQueryable(targetEntityType); var innerQuerySourceReferenceExpression = new QuerySourceReferenceExpression(_queryModel.MainFromClause); var leftKeyAccess = CreateKeyAccessExpression( querySourceReferenceExpression, navigation.IsDependentToPrincipal() ? navigation.ForeignKey.Properties : navigation.ForeignKey.PrincipalKey.Properties); var rightKeyAccess = CreateKeyAccessExpression( innerQuerySourceReferenceExpression, navigation.IsDependentToPrincipal() ? navigation.ForeignKey.PrincipalKey.Properties : navigation.ForeignKey.Properties); _queryModel.BodyClauses.Add( new WhereClause( CreateKeyComparisonExpression(leftKeyAccess, rightKeyAccess))); return(_queryModel.MainFromClause.FromExpression); } var navigationJoin = navigationJoins .FirstOrDefault(nj => nj.QuerySource == querySourceReferenceExpression.ReferencedQuerySource && nj.Navigation == navigation); if (navigationJoin == null) { QuerySourceReferenceExpression innerQuerySourceReferenceExpression; var joinClause = BuildJoinFromNavigation( querySourceReferenceExpression, navigation, targetEntityType, optionalNavigationInChain, out innerQuerySourceReferenceExpression); var additionalBodyClauses = new List <IBodyClause>(); if (optionalNavigationInChain || !navigation.ForeignKey.IsRequired) { var groupJoinClause = new GroupJoinClause( joinClause.ItemName + "_group", typeof(IEnumerable <>).MakeGenericType(targetEntityType.ClrType), joinClause); var groupReferenceExpression = new QuerySourceReferenceExpression(groupJoinClause); var defaultIfEmptyMainFromClause = new MainFromClause(joinClause.ItemName + "_groupItem", joinClause.ItemType, groupReferenceExpression); var newQuerySourceReferenceExpression = new QuerySourceReferenceExpression(defaultIfEmptyMainFromClause); var defaultIfEmptyQueryModel = new QueryModel( defaultIfEmptyMainFromClause, new SelectClause(newQuerySourceReferenceExpression)); defaultIfEmptyQueryModel.ResultOperators.Add(new DefaultIfEmptyResultOperator(null)); var defaultIfEmptySubquery = new SubQueryExpression(defaultIfEmptyQueryModel); var defaultIfEmptyAdditionalFromClause = new AdditionalFromClause(joinClause.ItemName, joinClause.ItemType, defaultIfEmptySubquery); additionalBodyClauses.Add(defaultIfEmptyAdditionalFromClause); navigationJoins.Add( navigationJoin = new NavigationJoin( querySourceReferenceExpression.ReferencedQuerySource, navigation, groupJoinClause, additionalBodyClauses, optionalNavigationInChain, navigation.IsDependentToPrincipal(), new QuerySourceReferenceExpression(defaultIfEmptyAdditionalFromClause))); } else { navigationJoins.Add( navigationJoin = new NavigationJoin( querySourceReferenceExpression.ReferencedQuerySource, navigation, joinClause, additionalBodyClauses, optionalNavigationInChain, navigation.IsDependentToPrincipal(), innerQuerySourceReferenceExpression)); } } querySourceReferenceExpression = navigationJoin.QuerySourceReferenceExpression; navigationJoins = navigationJoin.NavigationJoins; } if (member == null) { return(querySourceReferenceExpression); } if (optionalNavigationInChain) { Expression memberAccessExpression = Expression.MakeMemberAccess(querySourceReferenceExpression, member); if (!member.PropertyType.IsNullableType()) { memberAccessExpression = Expression.Convert(memberAccessExpression, member.PropertyType.MakeNullable()); } var constantNullExpression = member.PropertyType.IsNullableType() ? Expression.Constant(null, member.PropertyType) : Expression.Constant(null, member.PropertyType.MakeNullable()); return(Expression.Condition( Expression.NotEqual( querySourceReferenceExpression, Expression.Constant(null, querySourceReferenceExpression.Type)), memberAccessExpression, constantNullExpression)); } return(Expression.MakeMemberAccess(querySourceReferenceExpression, member)); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { throw new NotSupportedException("Additional from clauses not supported"); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { throw new NotSupportedException("Additional froms not supported"); //_queryBuilder.FromParts.Add(fromClause.ItemType.Name); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { AppendLine(); TransformingVisitor.StringBuilder.Append($"from {fromClause.ItemType.ShortDisplayName()} {fromClause.ItemName} in "); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public static GroupJoinClause TryGetFlattenedGroupJoinClause([NotNull] this AdditionalFromClause additionalFromClause) => (additionalFromClause.FromExpression is SubQueryExpression subQueryExpression &&
public void SetUp() { _additionalFromClause = ExpressionHelper.CreateAdditionalFromClause(); _cloneContext = new CloneContext(new QuerySourceMapping()); }
/// <summary> /// Overrides the <see cref="QueryModelVisitorBase.VisitAdditionalFromClause(AdditionalFromClause, QueryModel, int)"/>. /// </summary> /// <param name="fromClause">The <see cref="AdditionalFromClause"/>.</param> /// <param name="queryModel">The <see cref="QueryModel"/>.</param> /// <param name="index">The index.</param> public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { throw new NotSupportedException($"Additional From clause is not supported: {fromClause.ToString()}."); }
/// <summary>Visits an additional from clause.</summary> /// <param name="fromClause">From clause to be visited.</param> /// <param name="queryModel">Query model containing given from clause.</param> /// <param name="index">Index of the where clause in the query model.</param> public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { _visitor.Visit(fromClause.FromExpression); _from = _visitor.RetrieveComponent(); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { if (fromClause.FromExpression is MemberExpression) { var member = (MemberExpression) fromClause.FromExpression; if (member.Expression is QuerySourceReferenceExpression) { // It's a join var visitor = new HqlGeneratorExpressionTreeVisitor(_parameterAggregator); visitor.Visit(fromClause.FromExpression); HqlJoin joinNode = _hqlTreeBuilder.Join( visitor.GetHqlTreeNodes().Single(), _hqlTreeBuilder.Alias(fromClause.ItemName)); _fromClause.AddChild(joinNode); } } base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { throw new NotSupportedException("Cannot select from multiple sources."); //base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { _namer.Add(fromClause); }
/// <summary> /// Additional from clauses attached to the top here. /// </summary> /// <param name="fromClause"></param> /// <param name="queryModel"></param> /// <param name="index"></param> public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { _qmContextStack.Peek().AddFromItem(fromClause); _exprVisitor.Visit(fromClause.FromExpression); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) => fromClause.TransformExpressions(TransformingVisitor.Visit);
/// <inheritdoc /> public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { LogWriter.WriteLine($"VisitAdditionalFromClause {fromClause}"); base.VisitAdditionalFromClause(fromClause, queryModel, index); }