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();
}
}