Search code examples
c#.net-corelinq-to-sqlgraphqlazure-cosmosdb

Mapping GraphQL query to Select() linq to sql


I am building an Web API with .NET core using GraphQL and DocumentDb.

In theory, GraphQL is optimized the data is shipped across the network and thus avoid over-fetching data. But I recognize that the backend server and database is doing the extra unnecessary work (query the entire document) when querying the database.

The best strategy here is using Select() to specific properties we need to fetch. But I have no idea how to build the expression from client's query that so complex.

Any help really appreciated.

Thanks


Solution

  • For translating linq-expressions to graphql-query you can use library: https://github.com/RDavydenko/SmartGraphQLClient

    1. Install Nuget-package:
    Install-Package SmartGraphQLClient
    
    1. Add services to DI:
    services.AddSmartGraphQLClient();
    
    1. Use linq-syntax:
    using SmartGraphQLClient;
    
    GraphQLHttpClient client = ... // from DI
    
    var users = await client.Query<UserModel>("users")
        .Include(x => x.Roles)
        .ThenInclude(x => x.Users)
        .Where(x => x.UserName.StartsWith("A") || x.Roles.Any(r => r.Code == RoleCode.ADMINISTRATOR))
        .Select(x => new 
        {
            x.Id,
            Name = x.UserName,
            x.Roles,
            IsAdministrator = x.Roles.Any(r => r.Code == RoleCode.ADMINISTRATOR)
        })
        .Skip(5)
        .Take(10)
        .Argument("secretKey", "1234")
        .ToListAsync();
    

    Your request will be translated to graphql-query:

    { 
        users (
          where: {
            or: [ 
              { userName: { startsWith: "A" } }
              { roles: { some: { code: { eq: ADMINISTRATOR } } } }
            ]
          }
          skip: 5
          take: 10
          secretKey: "1234"
      ) {
            id
            userName
            roles {
                code
                name
                description
                id
                users {
                    userName
                    age
                    id
                }
            }
        }
    }