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