private static ApplyProjection CreateApplicatorAsync <TEntityType>() { return((context, input) => { if (input is null) { return input; } // if projections are already applied we can skip var skipProjection = context.LocalContextData.TryGetValue(SkipProjectionKey, out object?skip) && skip is true; // ensure sorting is only applied once context.LocalContextData = context.LocalContextData.SetItem(SkipProjectionKey, true); if (skipProjection) { return input; } var visitorContext = new QueryableProjectionContext( context, context.ObjectType, context.Field.Type.UnwrapRuntimeType()); var visitor = new QueryableProjectionVisitor(); visitor.Visit(visitorContext); Expression <Func <TEntityType, TEntityType> > projection = visitorContext.Project <TEntityType>(); input = input switch { IQueryable <TEntityType> q => q.Select(projection), IEnumerable <TEntityType> e => e.AsQueryable().Select(projection), QueryableExecutable <TEntityType> ex => ex.WithSource(ex.Source.Select(projection)), _ => input }; return input; }); }
public override FieldMiddleware CreateExecutor <TEntityType>() { return(next => context => ExecuteAsync(next, context)); async ValueTask ExecuteAsync( FieldDelegate next, IMiddlewareContext context) { // first we let the pipeline run and produce a result. await next(context).ConfigureAwait(false); IQueryable <TEntityType>?source = null; if (context.Result is IQueryable <TEntityType> q) { source = q; } else if (context.Result is IEnumerable <TEntityType> e) { source = e.AsQueryable(); } if (source is not null) { var visitorContext = new QueryableProjectionContext( context, context.ObjectType, context.Field.Type.UnwrapRuntimeType()); var visitor = new QueryableProjectionVisitor(); visitor.Visit(visitorContext); context.Result = source.Select(visitorContext.Project <TEntityType>()); } } }
public override FieldMiddleware CreateExecutor <TEntityType>() { return(next => context => ExecuteAsync(next, context)); async ValueTask ExecuteAsync( FieldDelegate next, IMiddlewareContext context) { // first we let the pipeline run and produce a result. await next(context).ConfigureAwait(false); if (context.Result is not null) { var visitorContext = new QueryableProjectionContext( context, context.ObjectType, context.Field.Type.UnwrapRuntimeType()); var visitor = new QueryableProjectionVisitor(); visitor.Visit(visitorContext); Expression <Func <TEntityType, TEntityType> > projection = visitorContext.Project <TEntityType>(); context.Result = context.Result switch { IQueryable <TEntityType> q => q.Select(projection), IEnumerable <TEntityType> e => e.AsQueryable().Select(projection), QueryableExecutable <TEntityType> ex => ex.WithSource(ex.Source.Select(projection)), _ => context.Result }; } } } }