public override void VisitGroupJoinClause( [NotNull] GroupJoinClause groupJoinClause, [NotNull] QueryModel queryModel, int index) { Check.NotNull(groupJoinClause, nameof(groupJoinClause)); Check.NotNull(queryModel, nameof(queryModel)); var outerKeySelector = ReplaceClauseReferences(groupJoinClause.JoinClause.OuterKeySelector, groupJoinClause); var innerExpression = ReplaceClauseReferences(groupJoinClause.JoinClause.InnerSequence, groupJoinClause.JoinClause); var innerSequenceType = innerExpression.Type.GetSequenceType(); var innerItemParameter = Expression.Parameter(innerSequenceType); var innerElementScoped = innerSequenceType.IsConstructedGenericType && innerSequenceType.GetGenericTypeDefinition() == typeof(QuerySourceScope <>); Type innerElementType; if (innerElementScoped) { innerElementType = innerSequenceType.GetTypeInfo().GenericTypeArguments[0]; _querySourceMapping.AddMapping( groupJoinClause.JoinClause, QuerySourceScope.GetResult(innerItemParameter, groupJoinClause.JoinClause, innerElementType)); } else { innerElementType = innerSequenceType; _querySourceMapping.AddMapping(groupJoinClause.JoinClause, innerItemParameter); } var innerKeySelector = ReplaceClauseReferences(groupJoinClause.JoinClause.InnerKeySelector, groupJoinClause); var innerItemsParameter = Expression.Parameter(innerExpression.Type); _expression = Expression.Call( LinqOperatorProvider.GroupJoin.MakeGenericMethod( typeof(QuerySourceScope), innerSequenceType, outerKeySelector.Type, typeof(QuerySourceScope)), _expression, innerExpression, Expression.Lambda(outerKeySelector, QuerySourceScopeParameter), Expression.Lambda(innerKeySelector, innerItemParameter), Expression.Lambda( QuerySourceScope .Create( groupJoinClause, innerElementScoped ? Expression.Call( LinqOperatorProvider.Select .MakeGenericMethod( innerSequenceType, innerElementType), innerItemsParameter, Expression.Lambda( QuerySourceScope.GetResult( innerItemParameter, groupJoinClause.JoinClause, innerElementType), innerItemParameter)) : (Expression)innerItemsParameter, QuerySourceScopeParameter), QuerySourceScopeParameter, innerItemsParameter)); var expressionTypeInfo = _expression.Type.GetTypeInfo(); _querySourceMapping.AddMapping( groupJoinClause, QuerySourceScope .GetResult( QuerySourceScopeParameter, groupJoinClause, expressionTypeInfo.GetGenericTypeDefinition() .MakeGenericType(innerElementType))); if (expressionTypeInfo.GetGenericTypeDefinition() == typeof(IAsyncEnumerable <>)) { queryModel.TransformExpressions(ReplaceClauseReferences); } }
public override void VisitGroupJoinClause( [NotNull] GroupJoinClause groupJoinClause, [NotNull] QueryModel queryModel, int index) { Check.NotNull(groupJoinClause, "groupJoinClause"); Check.NotNull(queryModel, "queryModel"); var outerKeySelector = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(groupJoinClause) .VisitExpression(groupJoinClause.JoinClause.OuterKeySelector)); var innerExpression = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(groupJoinClause.JoinClause) .VisitExpression(groupJoinClause.JoinClause.InnerSequence)); var innerSequenceType = innerExpression.Type.GetSequenceType(); var innerItemParameter = Expression.Parameter(innerSequenceType); var innerElementScoped = innerSequenceType.IsConstructedGenericType && innerSequenceType.GetGenericTypeDefinition() == typeof(QuerySourceScope <>); Type innerElementType; if (innerElementScoped) { innerElementType = innerSequenceType.GetTypeInfo().GenericTypeArguments[0]; _querySourceMapping.AddMapping( groupJoinClause.JoinClause, QuerySourceScope.GetResult(innerItemParameter, groupJoinClause.JoinClause, innerElementType)); } else { innerElementType = innerSequenceType; _querySourceMapping.AddMapping(groupJoinClause.JoinClause, innerItemParameter); } var innerKeySelector = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(groupJoinClause) .VisitExpression(groupJoinClause.JoinClause.InnerKeySelector)); var innerItemsParameter = Expression.Parameter(innerExpression.Type); _expression = Expression.Call( _queryCompilationContext.LinqOperatorProvider.GroupJoin.MakeGenericMethod( typeof(QuerySourceScope), innerSequenceType, outerKeySelector.Type, typeof(QuerySourceScope)), _expression, innerExpression, Expression.Lambda(outerKeySelector, QuerySourceScopeParameter), Expression.Lambda(innerKeySelector, innerItemParameter), Expression.Lambda( QuerySourceScope .Create( groupJoinClause, innerElementScoped ? Expression.Call( _queryCompilationContext.LinqOperatorProvider.Select .MakeGenericMethod( innerSequenceType, innerElementType), innerItemsParameter, Expression.Lambda( QuerySourceScope.GetResult( innerItemParameter, groupJoinClause.JoinClause, innerElementType), new[] { innerItemParameter })) : (Expression)innerItemsParameter, QuerySourceScopeParameter), new[] { QuerySourceScopeParameter, innerItemsParameter })); _querySourceMapping.AddMapping( groupJoinClause, QuerySourceScope .GetResult( QuerySourceScopeParameter, groupJoinClause, typeof(IEnumerable <>).MakeGenericType(innerElementType))); }
public override void VisitJoinClause( [NotNull] JoinClause joinClause, [NotNull] QueryModel queryModel, int index) { Check.NotNull(joinClause, nameof(joinClause)); Check.NotNull(queryModel, nameof(queryModel)); var outerKeySelector = ReplaceClauseReferences(joinClause.OuterKeySelector, joinClause); var innerSequenceExpression = ReplaceClauseReferences(joinClause.InnerSequence, joinClause); var innerSequenceType = innerSequenceExpression.Type.GetSequenceType(); var innerItemParameter = Expression.Parameter(innerSequenceType); var innerElementScoped = innerSequenceType.IsConstructedGenericType && innerSequenceType.GetGenericTypeDefinition() == typeof(QuerySourceScope <>); Type innerElementType; if (innerElementScoped) { innerElementType = innerSequenceType.GetTypeInfo().GenericTypeArguments[0]; _querySourceMapping.AddMapping( joinClause, QuerySourceScope.GetResult(innerItemParameter, joinClause, innerElementType)); } else { innerElementType = innerSequenceType; _querySourceMapping.AddMapping(joinClause, innerItemParameter); } var innerKeySelector = ReplaceClauseReferences(joinClause.InnerKeySelector, joinClause); _expression = Expression.Call( LinqOperatorProvider.Join.MakeGenericMethod( typeof(QuerySourceScope), innerSequenceType, outerKeySelector.Type, typeof(QuerySourceScope)), _expression, innerSequenceExpression, Expression.Lambda(outerKeySelector, QuerySourceScopeParameter), Expression.Lambda(innerKeySelector, innerItemParameter), Expression.Lambda( QuerySourceScope .Create( joinClause, innerElementScoped ? QuerySourceScope.GetResult(innerItemParameter, joinClause, innerElementType) : innerItemParameter, QuerySourceScopeParameter), QuerySourceScopeParameter, innerItemParameter)); _querySourceMapping.ReplaceMapping( joinClause, QuerySourceScope.GetResult(QuerySourceScopeParameter, joinClause, innerElementType)); }