// Mutation should be null UNLESS adding a mutation at the schema level
        internal GraphQLFieldBuilder <TContext, TField> AddFieldInternal <TArgs, TField>(string name, Func <TArgs, Expression <Func <TContext, TEntity, TField> > > exprFunc)
        {
            var field = GraphQLField.New(_schema, name, exprFunc, typeof(TField), _type);

            _type.OwnFields.Add(field);
            return(new GraphQLFieldBuilder <TContext, TField>(field));
        }
        // Mutation should be null UNLESS adding a mutation at the schema level
        internal GraphQLFieldBuilder <TContext, TField> AddListMutationInternal <TArgs, TField, TMutReturn>(string name, Func <TArgs, TMutReturn, Expression <Func <TContext, TEntity, IEnumerable <TField> > > > exprFunc, Func <TContext, TArgs, TMutReturn> mutation)
        {
            var field = GraphQLField.NewMutation(_schema, name, exprFunc, typeof(IEnumerable <TField>), _type, mutation);

            _type.OwnFields.Add(field);
            return(new GraphQLFieldBuilder <TContext, TField>(field));
        }
        public GraphQLFieldBuilder <TContext, TField> AddPostField <TField>(string name, Func <TField> fieldFunc)
        {
            var field = GraphQLField.Post(_schema, name, fieldFunc);

            _type.OwnFields.Add(field);
            return(new GraphQLFieldBuilder <TContext, TField>(field));
        }
Beispiel #4
0
 private static Type GetFieldPropertyType(GraphQLField field)
 {
     return(field.Type.TypeKind == TypeKind.SCALAR
         ? (field.IsList
             ? typeof(IEnumerable <>).MakeGenericType(field.Type.CLRType)
             : TypeHelpers.MakeNullable(field.Type.CLRType))
         : typeof(object));
 }
        // unsafe generic magic to create a GQLField instance
        private GraphQLField CreateGenericField(PropertyInfo prop)
        {
            // build selector expression, e.g.: (db, p) => p.Id
            var entityParam = Expression.Parameter(typeof(TEntity), "p");
            var memberExpr  = Expression.MakeMemberAccess(entityParam, prop);
            var lambda      = Expression.Lambda(memberExpr, GraphQLSchema <TContext> .DbParam, entityParam);

            // build args func wrapping selector expression, e.g. o => (db, p) => p.Id
            var objectParam = Expression.Parameter(typeof(object), "o");
            var argsExpr    = Expression.Lambda(Expression.Quote(lambda), objectParam);
            var exprFunc    = argsExpr.Compile();

            return(GraphQLField.New(_schema, prop.Name.ToCamelCase(), (Func <object, LambdaExpression>)exprFunc, prop.PropertyType, _type));
        }
Beispiel #6
0
        public static object Execute
            (GraphQLSchema <TContext> schema, TContext context, GraphQLField field, ExecSelection <Info> query)
        {
            var mutReturn = field.RunMutation(context, query.Arguments.Values());

            var queryableFuncExpr = field.GetExpression(query.Arguments.Values(), mutReturn);
            var replaced          = (LambdaExpression)ParameterReplacer.Replace(queryableFuncExpr, queryableFuncExpr.Parameters[0], GraphQLSchema <TContext> .DbParam);

            // sniff queryable provider to determine how selector should be built
            var dummyQuery        = replaced.Compile().DynamicInvoke(context, null);
            var queryType         = dummyQuery.GetType();
            var expressionOptions = schema.GetOptionsForQueryable(queryType);

            if (expressionOptions.UseBaseType)
            {
                queryType         = queryType.BaseType;
                expressionOptions = schema.GetOptionsForQueryable(queryType);
            }

            var queryExecSelections = query.Selections.Values();
            var selector            = GetSelector(schema, field.Type, queryExecSelections, expressionOptions);

            if (field.ResolutionType != ResolutionType.Unmodified)
            {
                var selectorExpr = Expression.Quote(selector);

                // TODO: This should be temporary - queryable and enumerable should both work
                var body = replaced.Body;
                if (body.NodeType == ExpressionType.Convert)
                {
                    body = ((UnaryExpression)body).Operand;
                }

                var call        = Expression.Call(typeof(Queryable), "Select", new[] { field.Type.CLRType, field.Type.QueryType }, body, selectorExpr);
                var expr        = Expression.Lambda(call, GraphQLSchema <TContext> .DbParam);
                var transformed = expr.Compile().DynamicInvoke(context);

                object results;
                switch (field.ResolutionType)
                {
                case ResolutionType.Unmodified:
                    throw new Exception("Queries cannot have unmodified resolution. May change in the future.");

                case ResolutionType.ToList:
                    var list = GenericQueryableCall <IEnumerable <object> >(transformed, q => q.ToList());
                    results = list.Select(o => MapResults(o, queryExecSelections, schema)).ToList();
                    break;

                case ResolutionType.FirstOrDefault:
                    var fod = GenericQueryableCall(transformed, q => q.FirstOrDefault());
                    results = MapResults(fod, queryExecSelections, schema);
                    break;

                case ResolutionType.First:
                    var first = GenericQueryableCall(transformed, q => q.FirstOrDefault());
                    results = MapResults(first, queryExecSelections, schema);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                return(results);
            }
            else
            {
                var invocation = Expression.Invoke(selector, replaced.Body);
                var expr       = Expression.Lambda(invocation, GraphQLSchema <TContext> .DbParam);
                var result     = expr.Compile().DynamicInvoke(context);
                return(MapResults(result, queryExecSelections, schema));
            }
        }
 internal GraphQLFieldBuilder(GraphQLField field)
 {
     _field = field;
 }