Introducing GraphQLinq - Strongly Typed GraphQL Queries with LINQ to GraphQL.

Apr 27, 2021·
Giorgi Dalakishvili
Giorgi Dalakishvili
· 3 min read
blog dotnet

Consuming a GraphQL api in C# is straightforward with either using HttpClient directly or using a client library such as GraphQL.Client but both suffer from the same problems: The GraphQL queries do not go through any compile-time checking, and any mistake in the query isn’t discovered until you execute the query at runtime. For example, to query SpaceX GraphQL API for all missions where the manufacturer is Orbital ATK you need to run the following query:

{
  missions (find: {manufacturer: "Orbital ATK"}) {
    id
    name
    description
    twitter
    website
    wikipedia
    manufacturers
  }
}

.Net solved the same problem for SQL with LINQ: LINQ queries are first-class language objects and are strongly typed. This way, there are no hardcoded queries in the project, and the LINQ queries are type-checked by the compiler.

In this article, I will show how GraphQLinq - a LINQ to GraphQL library solves this problem.

Getting Started with GraphQLinq

GraphQLinq consists of two parts: GraphQLinq.Scaffolding for generating strongly typed classes from the GrapQL endpoint and client library, GraphQLinq.Client, for writing and executing LINQ to GraphQL queries.

GraphQLinq.Scaffolding is a .NET tool, so run the following command to install it:

dotnet tool install --global --version 1.0.0-beta GraphQLinq.Scaffolding

This will install the tool globally and make it available for all projects.

Next, navigate to your project folder and run the graphql-scaffold tool to scaffold the client-side code:

graphqlinq-scaffold https://api.spacex.land/graphql -o SpaceX -n SpaceX

This will generate the code in the SpaceX folder (specified by the o option) and use SpaceX as a namespace too.

Scaffolding GraphQL client with GraphQLinq.Scaffolding
Scaffolding GraphQL client with GraphQLinq.Scaffolding

Now, install the GraphQLinq.Client package in your project to write some LINQ to GraphQL queries:

dotnet add package GraphQLinq.Client --version 1.0.0-beta

Running GraphQL Queries with LINQ

The scaffolding tool generates QueryContext class that serves as an entry point for writing and running LINQ queries. For example, you can write the above graphQL query like this:

var spaceXContext = new QueryContext();

var missionsQuery = spaceXContext.Missions(new MissionsFind { Manufacturer = "Orbital ATK" }, null, null)
                                 .Include(mission => mission.Manufacturers);
var missions = missionsQuery.ToList();

This LINQ query will generate a graphQL query that includes all primitive properties of the Mission class and also includes the list of manufacturers in the query.

Here are a couple of more LINQ to GraphQL queries:

Query all Primitive Properties of a Type

Quering for all primitive properties is very straightforward:

var spaceXContext = new QueryContext();

var company = spaceXContext.Company().ToItem();

Query Specific Properties

var companySummary = spaceXContext.Company().Select(c => new CompanySummary
{
    Ceo = c.Ceo,
    Name = c.Name,
    Headquarters = c.Headquarters
}).ToItem();

/// Alternatively, use an anonymous object

var companySummaryAnonymous = spaceXContext.Company().Select(c => new { c.Ceo, c.Name, c.Headquarters }).ToItem();

Include Navigation Properties

var companyWithHeadquartersAndLinks = spaceXContext.Company()
                                      .Include(info => info.Headquarters)
                                      .Include(info => info.Links).ToItem();

View Generated Query

To view the generated GraphQL query, call ToString on the LINQ query itself. You will get the GraphQL query together with the variables bound to the query.

var missionsQuery = spaceXContext.Missions(new MissionsFind { Manufacturer = "Orbital ATK" }, null, null)
                                 .Include(mission => mission.Manufacturers);

var query = missionsQuery.Query;
var fullQuery = missionsQuery.ToString();

After executing the above code snippet query will be equal to:

query ($find: MissionsFind) { result: missions (find: $find) { 
  description
  id
  name
  twitter
  website
  wikipedia
  manufacturers
 }}

and fullQuery will be:

{"query":"query ($find: MissionsFind) { result: missions (find: $find) { 
  description
  id
  name
  twitter
  website
  wikipedia
  manufacturers
 }}","variables":{"find":{"manufacturer":"Orbital ATK"}}}

Roadmap

The library is in the early stages and does not support all possible GraphQL schemas and queries. Check open issues for a list of proposed features and known issues.

If you find the library useful, don’t forget to ⭐ the GitHub repository. If you have any questions or suggestions, you are welcome to submit an issue or send a PR.

I also presented GraphQLinq on On .NET Live: LINQ to GraphQL: Query GraphQL with LINQ syntax.

Giorgi Dalakishvili
Authors
Backend Engineer & Software Architect · 3x Microsoft MVP · International Speaker

I’m a backend engineer and software architect with 17+ years of .NET, mostly in banking and fintech: payment and transaction processing, public APIs, and the internal platforms other teams build on. I’ve led teams and a platform unit, and I stay hands-on in the code, increasingly through AI coding agents like Claude Code and Codex.

Alongside that, I build open-source .NET libraries and developer tools with 44M+ NuGet downloads: DuckDB.NET, EntityFramework.Exceptions, EFCore.Visualizer and others. That work sits where .NET meets the database: native interop, Native AOT extensions for DuckDB and PostgreSQL, and tooling that makes query plans easier to debug. I also speak about .NET and databases at conferences like NDC, KCDC and .NET Conf.