public virtual Expression CreateScope( [NotNull] Expression expression, [NotNull] Type elementType, [NotNull] IQuerySource querySource) { Check.NotNull(expression, nameof(expression)); Check.NotNull(elementType, nameof(elementType)); Check.NotNull(querySource, nameof(querySource)); var innerItemParameter = Expression.Parameter(elementType); return (Expression.Call( LinqOperatorProvider.Select .MakeGenericMethod(elementType, typeof(QueryResultScope)), expression, Expression.Lambda( QueryResultScope .Create(querySource, innerItemParameter, QueryResultScopeParameter), innerItemParameter))); }
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 = CompileGroupJoinInnerSequenceExpression(groupJoinClause, queryModel); var innerSequenceType = innerExpression.Type.GetSequenceType(); var innerItemParameter = Expression.Parameter(innerSequenceType); var innerElementScoped = innerSequenceType.IsConstructedGenericType && innerSequenceType.GetGenericTypeDefinition() == typeof(QueryResultScope <>); Type innerElementType; var querySourceMapping = _queryCompilationContext.QuerySourceMapping; if (innerElementScoped) { innerElementType = innerSequenceType.GetTypeInfo().GenericTypeArguments[0]; querySourceMapping.AddMapping( groupJoinClause.JoinClause, QueryResultScope.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(QueryResultScope), innerSequenceType, outerKeySelector.Type, typeof(QueryResultScope)), _expression, innerExpression, Expression.Lambda(outerKeySelector, QueryResultScopeParameter), Expression.Lambda(innerKeySelector, innerItemParameter), Expression.Lambda( QueryResultScope .Create( groupJoinClause, innerElementScoped ? Expression.Call( LinqOperatorProvider.Select .MakeGenericMethod( innerSequenceType, innerElementType), innerItemsParameter, Expression.Lambda( QueryResultScope.GetResult( innerItemParameter, groupJoinClause.JoinClause, innerElementType), innerItemParameter)) : (Expression)innerItemsParameter, QueryResultScopeParameter), QueryResultScopeParameter, innerItemsParameter)); var expressionTypeInfo = _expression.Type.GetTypeInfo(); querySourceMapping.AddMapping( groupJoinClause, QueryResultScope .GetResult( QueryResultScopeParameter, groupJoinClause, expressionTypeInfo.GetGenericTypeDefinition() .MakeGenericType(innerElementType))); }