예제 #1
0
        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)));
        }
예제 #2
0
        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)));
        }