public static Expression <Func <T, T> > Project <T>(this QueryableProjectionContext context) { if (context.TryGetQueryableScope(out QueryableProjectionScope? scope)) { return(scope.Project <T>()); } throw ProjectionConvention_CouldNotProject(); }
public static QueryableProjectionScope AddScope( this QueryableProjectionContext context, Type runtimeType) { var parameterName = "p" + context.Scopes.Count; var closure = new QueryableProjectionScope(runtimeType, parameterName); context.Scopes.Push(closure); return(closure); }
public static bool TryGetQueryableScope( this QueryableProjectionContext ctx, [NotNullWhen(true)] out QueryableProjectionScope?scope) { if (ctx.Scopes.Count > 0 && ctx.Scopes.Peek() is QueryableProjectionScope queryableScope) { scope = queryableScope; return(true); } scope = null; return(false); }
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 }; } } } }