landmarkhw / Dapper.GraphQL

A .NET Core library designed to integrate the Dapper and graphql-dotnet projects with ease-of-use in mind and performance as the primary concern.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue to compiling

jefer94 opened this issue · comments

This is a part of code

using System;
using System.Collections.Generic;
using System.Text;

namespace Main.GraphQL.Models {
  public class User {
    //public string FirstName { get; set; }
    public int id { get; set; }
    //public string LastName { get; set; }
    public string nick { get; set; }
    public string name { get; set; }
    public string photo { get; set; }
    public string password { get; set; }
    public IList<Message> messages { get; set; }
    public IList<Channel> channels { get; set; }

    public User() {
      this.messages = new List<Message>();
      this.channels = new List<Channel>();
    }
  }
}
using System;
using System.Collections.Generic;
using System.Text;
using GraphQL.Language.AST;
using Dapper.GraphQL;
using Main.GraphQL.Models;
using Main;

namespace Main.GraphQL.QueryBuilders {
  public class UserQueryBuilder : IQueryBuilder<UserQueryBuilder> {
    private IQueryBuilder<MessageQueryBuilder> message;
    private IQueryBuilder<ChannelQueryBuilder> channel;

    public void User(IQueryBuilder<MessageQueryBuilder> message, IQueryBuilder<ChannelQueryBuilder> channel) {
      this.message = message;
      this.channel = channel;
    }

    public string id { get; }
    public string nick { get; set; }
    public string name { get; set; }
    public string photo { get; set; }
    public string password { get; set; }

    public SqlQueryContext Build(SqlQueryContext query, IHaveSelectionSet context, string alias) {
      var mergedAlias = $"{alias}Merged";

      var fields = context.GetSelectedFields();

      SQLBuilder.field("id", ref fields, ref query, mergedAlias);
      SQLBuilder.field("nick", ref fields, ref query, mergedAlias);
      SQLBuilder.field("name", ref fields, ref query, mergedAlias);
      SQLBuilder.field("photo", ref fields, ref query, mergedAlias);
      SQLBuilder.field("password", ref fields, ref query, mergedAlias);

      SQLBuilder.join<MessageQueryBuilder>("messages", $"{alias}Message", mergedAlias, ref fields, ref query, this.message);
      SQLBuilder.join<ChannelQueryBuilder>("channels", $"{alias}Channel", mergedAlias, ref fields, ref query, this.channel);

      return query;
    }
  }
}
using System;
using System.Collections.Generic;
using System.Text;
using GraphQL.Language.AST;
using Dapper.GraphQL;
using Main.GraphQL.Models;
using Main;

namespace Main {
  public static class SQLBuilder {
    public static void field(string field, ref IDictionary<string, Field> fields, ref SqlQueryContext query, string alias) {
      if (fields.ContainsKey(field)) {
        query.Select($"{alias}.{field}");
      }
    }

    public static void join<T>(string field, string alias, string parent, ref IDictionary<string, Field> fields, ref SqlQueryContext query, IQueryBuilder<T> obj/*, ref Fields func*/) {
      ;
      if (fields.ContainsKey(field)) {
        query.LeftJoin($"Phone {alias} ON {parent}.id_{alias} = {alias}.id");
        query = obj.Build(query, fields[field], alias);
      }
    }
  }
}
using Main.GraphQL.Models;
using GraphQL.Types;
using System;
using System.Collections.Generic;
using System.Text;

namespace Main.GraphQL.Types {
  public class UserType : ObjectGraphType<User> {
    public UserType() {
      Name = "user";
      Description = "An user.";

      Field<IntGraphType>(
        "id",
        description: "A unique identifier for the user.",
        resolve: context => context.Source?.id
      );

      Field<StringGraphType>(
        "nick",
        description: "The nickname of the user.",
        resolve: context => context.Source?.nick
      );

      Field<StringGraphType>(
        "name",
        description: "The name of the user.",
        resolve: context => context.Source?.name
      );

      Field<StringGraphType>(
        "photo",
        description: "The photo of the user.",
        resolve: context => context.Source?.photo
      );

      Field<StringGraphType>(
        "password",
        description: "The password of the user.",
        resolve: context => context.Source?.password
      );

      Field<ListGraphType<MessageType>>(
        "messages",
        description: "A list of messages for the user.",
        resolve: context => context.Source?.messages
      );

      Field<ListGraphType<ChannelType>>(
        "channels",
        description: "A list of channels for the user.",
        resolve: context => context.Source?.channels
      );
    }
  }
}
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Dapper.GraphQL;
using Main.GraphQL.Models;
using Main.GraphQL.QueryBuilders;
using Main.GraphQL.Types;

namespace Main {
  public class Startup {

    ...

    public void ConfigureServices(IServiceCollection services) {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

      // In production, the React files will be served from this directory
      services.AddSpaStaticFiles(configuration => {
        configuration.RootPath = "ClientApp/build";
      });

      services.AddDapperGraphQL(options => {
        // Add GraphQL types
        options.AddType<UserType>();
        options.AddType<ChannelType>();
        options.AddType<MessageType>();
        options.AddType<FallacyType>();

        // Add the GraphQL schema
        //options.AddSchema<ArgumentSchema>();
        //options.AddSchema<ChannelSchema>();

        // Add query builders for dapper
        options.AddQueryBuilder<User, UserQueryBuilder>();
        options.AddQueryBuilder<Channel, ChannelQueryBuilder>();
        options.AddQueryBuilder<Message, MessageQueryBuilder>();
        options.AddQueryBuilder<Fallacy, FallacyQueryBuilder>();
      });
    }

    ...

  }
}

Startup.cs(42,9): error CS0311: The type 'Main.GraphQL.QueryBuilders.UserQueryBuilder' cannot be used as type parameter 'TQueryBuilder' in the generic type or method 'DapperGraphQLOptions.AddQueryBuilder<TModelType, TQueryBuilder>()'. There is no implicit reference conversion from 'Main.GraphQL.QueryBuilders.UserQueryBuilder' to 'Dapper.GraphQL.IQueryBuilder<Main.GraphQL.Models.User>'. [/home/jefer/prog/main/main.csproj]
Startup.cs(43,9): error CS0311: The type 'Main.GraphQL.QueryBuilders.ChannelQueryBuilder' cannot be used as type parameter 'TQueryBuilder' in the generic type or method 'DapperGraphQLOptions.AddQueryBuilder<TModelType, TQueryBuilder>()'. There is no implicit reference conversion from 'Main.GraphQL.QueryBuilders.ChannelQueryBuilder' to 'Dapper.GraphQL.IQueryBuilder<Main.GraphQL.Models.Channel>'. [/home/jefer/prog/main/main.csproj]
Startup.cs(44,9): error CS0311: The type 'Main.GraphQL.QueryBuilders.MessageQueryBuilder' cannot be used as type parameter 'TQueryBuilder' in the generic type or method 'DapperGraphQLOptions.AddQueryBuilder<TModelType, TQueryBuilder>()'. There is no implicit reference conversion from 'Main.GraphQL.QueryBuilders.MessageQueryBuilder' to 'Dapper.GraphQL.IQueryBuilder<Main.GraphQL.Models.Message>'. [/home/jefer/prog/main/main.csproj]
Startup.cs(45,9): error CS0311: The type 'Main.GraphQL.QueryBuilders.FallacyQueryBuilder' cannot be used as type parameter 'TQueryBuilder' in the generic type or method 'DapperGraphQLOptions.AddQueryBuilder<TModelType, TQueryBuilder>()'. There is no implicit reference conversion from 'Main.GraphQL.QueryBuilders.FallacyQueryBuilder' to 'Dapper.GraphQL.IQueryBuilder<Main.GraphQL.Models.Fallacy>'. [/home/jefer/prog/main/main.csproj]

The build failed. Please fix the build errors and run again.

Try changing:
public class UserQueryBuilder : IQueryBuilder<UserQueryBuilder> {
to
public class UserQueryBuilder : IQueryBuilder<User> {

Also, UserQueryBuilder ctor needs some love.

Oh, I'm sorry, I think that this is a issue, now it's work

It'd great that the builder

using System;
using System.Collections.Generic;
using System.Text;
using GraphQL.Language.AST;
using Dapper.GraphQL;
using Main.GraphQL.Models;
using Main;

namespace Main {
  public static class SQLBuilder {
    public static void field(string field, ref IDictionary<string, Field> fields, ref SqlQueryContext query, string alias) {
      if (fields.ContainsKey(field)) {
        query.Select($"{alias}.{field}");
      }
    }

    public static void join<T>(string field, string alias, string parent, ref IDictionary<string, Field> fields, ref SqlQueryContext query, IQueryBuilder<T> obj/*, ref Fields func*/) {
      if (fields.ContainsKey(field)) {
        query.LeftJoin($"Phone {alias} ON {parent}.id_{alias} = {alias}.id");
        query = obj.Build(query, fields[field], alias);
      }
    }
  }
}

Was part of Dapper.GraphQL, that think you?

This seems a bit beyond the scope of what I'd like to support in Dapper.GraphQL - you're welcome to write extension methods on SqlQueryContext that would accomplish similar goals, but I'd rather stay away from that in the base libraries if we can.

Thanks!