public IEnumerableResolver Select()

in src/Epam.GraphQL/Configuration/Implementations/FieldResolvers/EnumerableAsyncFuncResolverBase.cs [76:167]


        public IEnumerableResolver<TEntity, TSelectType, TExecutionContext> Select<TSelectType>(Expression<Func<TEntity, TReturnType, TSelectType>> selector)
        {
            var factorizationResult = ExpressionHelpers.Factorize(selector);
            AddMembers(factorizationResult);

            var proxiedSelector = new Lazy<Func<Proxy<TEntity>, TTransformedReturnType, TSelectType>>(() =>
            {
                var outerProxyParam = Expression.Parameter(typeof(Proxy<TEntity>));
                var innerProxyParam = Expression.Parameter(typeof(TTransformedReturnType));
                var outers = factorizationResult.LeftExpressions
                    .Select(e => OuterProxyAccessor.Rewrite(e, e).CastFirstParamTo<Proxy<TEntity>>())
                    .Select(e => e.Body.ReplaceParameter(e.Parameters[0], outerProxyParam))
                    .ToList();

                var inners = factorizationResult.RightExpressions
                    .Select(TransformInnerExpression)
                    .Select(e => e.Body.ReplaceParameter(e.Parameters[0], innerProxyParam))
                    .ToList();

                var paramMap = new Dictionary<ParameterExpression, Expression>();

                var parameters = factorizationResult.Expression.Parameters;

                for (int i = 0; i < outers.Count; i++)
                {
                    paramMap.Add(parameters[i], outers[i]);
                }

                for (int i = 0; i < inners.Count; i++)
                {
                    paramMap.Add(parameters[i + outers.Count], inners[i]);
                }

                var exprBody = factorizationResult.Expression.Body.ReplaceParameters(paramMap);
                var expr = Expression.Lambda<Func<Proxy<TEntity>, TTransformedReturnType, TSelectType>>(exprBody, outerProxyParam, innerProxyParam);

                var compiledExpr = expr.Compile();

                return compiledExpr;
            });

            var compiledSelector = new Lazy<Func<TEntity, TTransformedReturnType, TSelectType>>(() =>
            {
                var outerParam = Expression.Parameter(typeof(TEntity));
                var innerProxyParam = Expression.Parameter(typeof(TTransformedReturnType));
                var outers = factorizationResult.LeftExpressions
                    .Select(e => e.Body.ReplaceParameter(e.Parameters[0], outerParam))
                    .ToList();

                var inners = factorizationResult.RightExpressions
                    .Select(TransformInnerExpression)
                    .Select(e => e.Body.ReplaceParameter(e.Parameters[0], innerProxyParam))
                    .ToList();

                var paramMap = new Dictionary<ParameterExpression, Expression>();

                var parameters = factorizationResult.Expression.Parameters;

                for (int i = 0; i < outers.Count; i++)
                {
                    paramMap.Add(parameters[i], outers[i]);
                }

                for (int i = 0; i < inners.Count; i++)
                {
                    paramMap.Add(parameters[i + outers.Count], inners[i]);
                }

                var exprBody = factorizationResult.Expression.Body.ReplaceParameters(paramMap);
                var expr = Expression.Lambda<Func<TEntity, TTransformedReturnType, TSelectType>>(exprBody, outerParam, innerProxyParam);

                var compiledExpr = expr.Compile();

                return compiledExpr;
            });

            return new EnumerableAsyncFuncResolver<TEntity, TSelectType, TExecutionContext>(
                FieldName,
                ctx => Resolver(ctx).Then(Continuation),
                ctx => ProxiedResolver(ctx).Then(ProxiedContinuation),
                OuterProxyAccessor);

            IEnumerable<TSelectType> Continuation(TEntity source, IEnumerable<TTransformedReturnType> items)
            {
                return items.Select(item => compiledSelector.Value(source, item)).AsEnumerable();
            }

            IEnumerable<TSelectType> ProxiedContinuation(Proxy<TEntity> source, IEnumerable<TTransformedReturnType> items)
            {
                return items.Select(item => proxiedSelector.Value(source, item)).AsEnumerable();
            }
        }