chkimes / graphql-net

Convert GraphQL to IQueryable
MIT License
891 stars 86 forks source link

EF issue - user is a value type and cannot be selected from #92

Closed bobloblaws93 closed 6 years ago

bobloblaws93 commented 6 years ago

Hi, all I'm having a bit of an issue with graphql. I'm trying to query my dataset but im running into problems the moment I try execute a query. I get the exeception:

GraphQL.Parser.SourceException: 'field ``user'' is a value type and cannot be selected from'

My code is as follows:

   public void test() {
         var schema = GraphQL<AdtDbContext>.CreateDefaultSchema(() => new AdtDbContext());
         schema.AddType<NTC_TC_MAINS>().AddAllFields();            
         var gql = new GraphQL<AdtDbContext>(schema);
         schema.AddField("user", new { NAME = "-1" }, (db, args) => db.NTC_TC_MAINS.SingleOrDefault(u => u.TC_NAME == args.NAME));
         schema.Complete();
         var qresult = gql.ExecuteQuery("{user(NAME:\"Hudson\") {tC_NAME}}");
         Console.WriteLine(JsonConvert.SerializeObject(qresult, Formatting.Indented));
        }

With the following DBset: public DbSet<NTC_TC_MAINS> NTC_TC_MAINS { get; set; }

typeselectedfrom

The exception is as follows is as follows: GraphQL.Parser.SourceException occurred HResult=0x80131500 Message=field ``user'' is a value type and cannot be selected from Source=GraphQL.Parser StackTrace:

Any advice into solving this would be greatly helpful!
chkimes commented 6 years ago

What's the query you're running? Is NTC_TC_MAINS a class or a struct?

bobloblaws93 commented 6 years ago

Thanks for Replying! NTC_TC_MAINS is a class as is defined as follows:

namespace ATD.Domain.Entities
{
    [Table("NTC_TC_MAINS")]
    public class NTC_TC_MAINS
    {
        [Key]
        [MaxLength(100)]
        public string ID { get; set; }
        [Required]
        [MaxLength(1000)]
        public string TC_NAME { get; set; }
        [Required]
        public int TC_TYPE_ID { get; set; }
        [Required]
        public int TC_SUB_TYPE_ID { get; set; }
        [Required]
        public int TC_CERT_TYPE_ID { get; set; }
        [MaxLength(200)]
        public string TC_CERT_DOC { get; set; }
        [MaxLength(200)]
        public string TC_LOGO { get; set; }
        [MaxLength(4000)]
        public string TC_VISION { get; set; }
        [MaxLength(4000)]
        public string TC_DESC { get; set; }
        [Required]
        public int TC_AFFI_ID { get; set; }
     }
}

The main query im trying to run is to find any NTC_TC_MAIN with the name "Hudson".

    {
     user(NAME:\"Hudson\") 
      {
        tC_NAME,tC_LOGO,tC_VISION
      }
    }

I was running into a similar issue as #49, where I inherited a database with names that are all uppercased.

I don't know if it helps but everything works fine the moment I I grab a list and instantiate a new context like so, it works:

        class Context
        {
            public IList<NTC_TC_MAINS> ntc { get; set; }
        }

        public void test()
        {
            List<NTC_TC_MAINS> allTCs = null;
            using (AtduDbContext context = new AtduDbContext())
            {
                allTCs = context.NTC_TC_MAINS.Select(t => (t)).ToList();

                var schema = GraphQL<Context>.CreateDefaultSchema(() =>
                    new Context
                    {
                        ntc = allTCs
                    });
                schema.AddType<NTC_TC_MAINS>().AddAllFields();
                schema.AddField("user", new { NAME = "-1" }, (C, args) => C.ntc.SingleOrDefault(u => u.TC_NAME == args.NAME));
                schema.Complete();
                var gql = new GraphQL<Context>(schema);
                var qresult = gql.ExecuteQuery("{user(NAME:\"Hudson\") {tC_NAME,tC_LOGO,tC_VISION}}");
                System.Diagnostics.Debug.Write("graphsqlul" + (JsonConvert.SerializeObject(qresult, Formatting.Indented)));
            }

But I don't want to call and grab the entire list all the time. Would rather be able to run the graphQL query and filter based on that.

chkimes commented 6 years ago

Can you try using FirstOrDefault?

bobloblaws93 commented 6 years ago

changed to: schema.AddField("user", new { id = "-1" }, (db, args) => db.NTC_TC_MAINS.Where(u => u.TC_NAME == args.id).FirstOrDefault()); Still gives me the same exception though

chkimes commented 6 years ago

AddField should return a GraphQLFieldBuilder. Can you assign that to a variable and inspect the private fields in the debugger (expand the _field field and its Type property), then paste the results here?

On Tue, Mar 27, 2018 at 10:49 AM ronnpang1 notifications@github.com wrote:

changed to: schema.AddField("user", new { id = "-1" }, (db, args) => db.NTC_TC_MAINS.Where(u => u.TC_NAME == args.id).FirstOrDefault()); Still gives me the same exception though

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ckimes89/graphql-net/issues/92#issuecomment-376553794, or mute the thread https://github.com/notifications/unsubscribe-auth/AB2KwpwteFSqOemtGFM85f2IlnHVmBJHks5tilGOgaJpZM4S70q9 .

bobloblaws93 commented 6 years ago

Expanding the _fields gives: prnt1 Expanding the type yields: prnt2

chkimes commented 6 years ago

So the immediate issue is that type.IsScalar is true, which is definitely not correct. I'll have to think some on why that could be.

Is it possible that NTC_TC_MAINS is defined twice in your project, and that the one used in schema.AddType<NTC_TC_MAINS>().AddAllFields(); is not the same as the one used in db.NTC_TC_MAINS?

On Tue, Mar 27, 2018 at 11:25 AM ronnpang1 notifications@github.com wrote:

Expanding the _fields gives: [image: prnt1] https://user-images.githubusercontent.com/4573812/37977293-717b3b4c-31b1-11e8-88c6-8a76a44e7826.png Expanding the type yields: [image: prnt2] https://user-images.githubusercontent.com/4573812/37977325-7c7c1b74-31b1-11e8-97ae-78f69125e348.png

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ckimes89/graphql-net/issues/92#issuecomment-376566897, or mute the thread https://github.com/notifications/unsubscribe-auth/AB2KwqKocyxU9qoU1m_gVLhPb8pO8ut_ks5tilnZgaJpZM4S70q9 .

bobloblaws93 commented 6 years ago

Oh man, you were absolutely right, NTC_MAIN was defined twice accidentally. Everything works now, thank you so much!