public Expression HandleLeave(
            SelectionVisitorContext context,
            IFieldSelection selection,
            Expression expression)
        {
            var argumentName = context.SelectionContext.FilterArgumentName;

            if (context.TryGetValueNode(argumentName, out IValueNode? filter) &&
                selection.Field.Arguments[argumentName].Type is InputObjectType iot &&
                iot is IFilterInputType fit)
            {
                var visitorContext = new QueryableFilterVisitorContext(
                    iot, fit.EntityType, context.Conversion, false);

                QueryableFilterVisitor.Default.Visit(filter, visitorContext);

                return(Expression.Call(
                           typeof(Enumerable),
                           "Where",
                           new[] { fit.EntityType },
                           expression,
                           visitorContext.CreateFilter()));
            }

            return(expression);
        }
Beispiel #2
0
        public Expression HandleLeave(
            SelectionVisitorContext context,
            IFieldSelection selection,
            Expression expression)
        {
            IFilterConvention convention   = context.SelectionContext.FilterConvention;
            NameString        argumentName = convention.GetArgumentName();

            if (context.TryGetValueNode(argumentName, out IValueNode? filter) &&
                selection.Field.Arguments[argumentName].Type is InputObjectType iot &&
                iot is IFilterInputType fit &&
                convention.TryGetVisitorDefinition(
                    out FilterExpressionVisitorDefinition? defintion))
            {
                var visitorContext = new QueryableFilterVisitorContext(
                    iot,
                    fit.EntityType,
                    defintion,
                    context.Conversion,
                    false);

                QueryableFilterVisitor.Default.Visit(filter, visitorContext);

                if (visitorContext.TryCreateLambda(
                        out LambdaExpression? filterExpression))
                {
                    return(Expression.Call(
                               typeof(Enumerable),
                               nameof(Enumerable.Where),
                               new[] { fit.EntityType },
                               expression,
                               filterExpression));
                }
                else
                {
                    context.ReportErrors(visitorContext.Errors);
                }
            }

            return(expression);
        }
Beispiel #3
0
        protected override void Configure(IObjectTypeDescriptor descriptor)
        {
            descriptor.ExtendQuery();

            descriptor
            .Field("games")
            .Type <NonNullType <ListType <NonNullType <GameType> > > >()
            .Argument("excludeDeleted", arg => arg.Type <BooleanType>()
                      .Description("Exclude games that have been marked as deleted. " +
                                   "Setting this to true is shorthand for retrieving games with the game_deleted metadata not set to \"true\".")
                      .DefaultValue(true))
            .AddFilterArguments <GameRecordQueryFilterInputType>()
            .Use(next => context =>
            {
                IValueNode valueNode = context.ArgumentValue <IValueNode>("where");
                bool excludeDeleted  = context.ArgumentValue <bool>("excludeDeleted");
                Expression <Func <IGameRecordQuery, bool> > excludeDeletedQuery = r =>
                                                                                  !r.Metadata.Any(r => r.MetadataKey == GameMetadataKeys.Deleted && r.MetadataValue == "true");

                var queryBuilder = context.SnowflakeService <IGameLibrary>();

                if (valueNode is null || valueNode is NullValueNode)
                {
                    if (!excludeDeleted)
                    {
                        context.Result = queryBuilder
                                         .GetAllGames()
                                         .ToList();
                    }
                    else
                    {
                        context.Result = queryBuilder.QueryGames(excludeDeletedQuery);
                    }
                    return(next.Invoke(context));
                }

                if (context.Field.Arguments["where"].Type is InputObjectType iot && iot is IFilterInputType)
                {
                    var filter = new QueryableFilterVisitorContext(iot, typeof(IGameRecordQuery), context.GetTypeConverter(), true);
                    QueryableFilterVisitor.Default.Visit(valueNode, filter);

                    var expr = filter.CreateFilter <IGameRecordQuery>();

                    if (!excludeDeleted)
                    {
                        context.Result = queryBuilder.QueryGames(expr).ToList();
                    }
                    else
                    {
                        // Invoke works fine here. We could use a expression tree visitor, but
                        // that is a lot more code than just using Invoke.
                        ParameterExpression param = expr.Parameters[0];
                        var combinedBody          = Expression.AndAlso(
                            expr.Body,
                            Expression.Invoke(excludeDeletedQuery, param)
                            );
                        var combinedLambda = Expression.Lambda <Func <IGameRecordQuery, bool> >(combinedBody, param);
                        context.Result     = queryBuilder.QueryGames(combinedLambda).ToList();
                    }
                }
                return(next.Invoke(context));
            })
            .UsePaging <GameType>();
        }