EntityGraphQL.AspNet 3.0.3
Entity GraphQL
A GraphQL library for .NET Core
Jump into the https://entitygraphql.github.io/ for documentation and to get started.
Entity GraphQL is a .NET Core (netstandard 2.1) library that allows you to easily build a GraphQL API on top of your data with the extensibility to bring multiple data sources together in the single GraphQL schema.
It can also be used to execute simple LINQ-style expressions at runtime against a given object which provides powerful runtime configuration.
Please explore, give feedback or join the development.
If you're looking for a dotnet library to generate code to query an API from a GraphQL schema see https://github.com/lukemurray/DotNetGraphQLQueryGen
Installation
Via Nuget
Quick Start with Entity Framework
Note: There is no dependency on EF. Queries are compiled to IQueryable or IEnumberable linq expressions. EF is not a requirement - any ORM working with LinqProvider or an in-memory object will work - although EF well is tested.
1. Define your data context (in this example an EF context)
public class DemoContext : DbContext {
public DemoContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder) {
// Set up your relations
}
public DbSet<Property> Properties { get; set; }
public DbSet<PropertyType> PropertyTypes { get; set; }
public DbSet<Location> Locations { get; set; }
}
public class Property {
public uint Id { get; set; }
public string Name { get; set; }
public PropertyType Type { get; set; }
public Location Location { get; set; }
}
public class PropertyType {
public uint Id { get; set; }
public string Name { get; set; }
public decimal Premium { get; set; }
}
public class Location {
public uint Id { get; set; }
public string Name { get; set; }
}
2. Create a route
Here is an example for a ASP.NET. You will also need to install EntityGraphQL.AspNet to use MapGraphQL. You can also build you own endpoint, see docs.
public class Startup {
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DemoContext>(opt => opt.UseInMemoryDatabase());
// This registers a SchemaProvider<DemoContext>
services.AddGraphQLSchema<DemoContext>();
}
public void Configure(IApplicationBuilder app, DemoContext db)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// default to /graphql endpoint
endpoints.MapGraphQL<DemoContext>();
});
}
}
This sets up 1 end point:
POSTat/graphqlwhere the body of the post is a GraphQL query- You can authorize that route how you would any ASP.NET route. See Authorization below for details on having parts of the schema requiring Authorization/Claims
Note - As of version 1.1+ the EntityGraphQL.AspNet extension helper uses System.Text.Json. Previous versions used JSON.NET.
3. Build awesome applications
You can now make a request to your API. For example
POST localhost:5000/graphql
{
properties { id name }
}
Will return the following result.
{
"data": {
"properties": [
{
"id": 11,
"name": "My Beach Pad"
},
{
"id": 12,
"name": "My Other Beach Pad"
}
]
}
}
Maybe you only want a specific property
{
property(id: 11) {
id name
}
}
Will return the following result.
{
"data": {
"property": {
"id": 11,
"name": "My Beach Pad"
}
}
}
If you need a deeper graph or relations, just ask
{
properties {
id
name
location {
name
}
type {
premium
}
}
}
Will return the following result.
{
"data": {
"properties": [
{
"id": 11,
"name": "My Beach Pad",
"location": {
"name": "Greece"
},
"type": {
"premium": 1.2
}
},
{
"id": 12,
"name": "My Other Beach Pad",
"location": {
"name": "Spain"
},
"type": {
"premium": 1.25
}
}
]
}
}
Visit documentation for more information.
Using expressions else where (EQL)
Lets say you have a screen in your application listing properties that can be configured per customer or user to only show exactly what they are interested in. Instead of having a bunch of checkboxes and complex radio buttons etc. you can allow a simple EQL statement to configure the results shown. Or use those UI components to build the query.
// This might be a configured EQL statement for filtering the results. It has a context of Property
(type.id = 2) or (type.id = 3) and type.name = "Farm"
This would compile to (Property p) => (p.Type.Id == 2 || p.Type.Id == 3) && p.Type.Name == "Farm";
This can then be used in various Linq functions either in memory or against an ORM.
// we create a schema provider to compile the statement against our Property type
var schemaProvider = SchemaBuilder.FromObject<Property>();
var compiledResult = EntityQueryCompiler.Compile(myConfigurationEqlStatement, schemaProvider);
// you get your list of Properties from you DB
var thingsToShow = myProperties.Where(compiledResult.LambdaExpression);
Another example is you want a customised calculated field. You can execute a compiled result passing in an instance of the context type.
// You'd take this from some configuration
var eql = @"if location.name = ""Mars"" then (cost + 5) * type.premium else (cost * type.premium) / 3"
var compiledResult = EntityQueryCompiler.Compile(eql, schemaProvider);
var theRealPrice = compiledResult.Execute<decimal>(myPropertyInstance);
Versioning
We do our best to follow Semantic Versioning:
Given a version number MAJOR.MINOR.PATCH, an increment in:
MAJORversion is when we make incompatible API changes,MINORversion is when we add functionality in a backwards compatible manner, andPATCHversion is when we make backwards compatible bug fixes.
Contribute & Join the Development
Please do. Pull requests are very welcome. See the open issues for bugs or features that would be useful.
No packages depend on EntityGraphQL.AspNet.
.NET Core 3.1
- EntityGraphQL (>= 3.0.3)
- Microsoft.AspNetCore.Authorization (>= 3.1.23)
.NET 5.0
- EntityGraphQL (>= 3.0.3)
- Microsoft.AspNetCore.Authorization (>= 5.0.15)
.NET 6.0
- EntityGraphQL (>= 3.0.3)
- Microsoft.AspNetCore.Authorization (>= 6.0.3)
| Version | Downloads | Last updated |
|---|---|---|
| 6.3.0 | 4 | 10/12/2026 |
| 6.2.4 | 5 | 10/02/2026 |
| 6.2.3 | 7 | 10/02/2026 |
| 6.2.2 | 6 | 10/02/2026 |
| 6.2.1 | 6 | 10/02/2026 |
| 6.2.0 | 4 | 10/02/2026 |
| 6.1.7 | 6 | 10/02/2026 |
| 6.1.6 | 7 | 10/02/2026 |
| 6.1.5 | 6 | 10/02/2026 |
| 6.1.4 | 7 | 10/02/2026 |
| 6.1.3 | 6 | 10/02/2026 |
| 6.1.2 | 6 | 10/02/2026 |
| 6.1.1 | 5 | 10/02/2026 |
| 6.1.0 | 6 | 10/02/2026 |
| 6.0.1 | 6 | 10/02/2026 |
| 6.0.0 | 6 | 10/02/2026 |
| 6.0.0-beta9 | 7 | 10/02/2026 |
| 6.0.0-beta8 | 6 | 10/02/2026 |
| 6.0.0-beta7 | 7 | 10/03/2026 |
| 6.0.0-beta6 | 5 | 10/02/2026 |
| 6.0.0-beta5 | 7 | 10/02/2026 |
| 6.0.0-beta4 | 6 | 10/02/2026 |
| 6.0.0-beta3 | 8 | 10/02/2026 |
| 6.0.0-beta2 | 9 | 10/04/2026 |
| 6.0.0-beta1 | 6 | 10/02/2026 |
| 5.7.3 | 6 | 10/02/2026 |
| 5.7.2 | 5 | 10/03/2026 |
| 5.7.1 | 5 | 10/03/2026 |
| 5.7.0 | 6 | 10/02/2026 |
| 5.6.1 | 4 | 10/02/2026 |
| 5.6.0 | 6 | 10/02/2026 |
| 5.5.3 | 6 | 10/02/2026 |
| 5.5.2 | 6 | 10/02/2026 |
| 5.5.1 | 7 | 10/02/2026 |
| 5.5.0 | 6 | 10/03/2026 |
| 5.4.6 | 9 | 10/02/2026 |
| 5.4.5 | 8 | 10/02/2026 |
| 5.4.4 | 7 | 10/03/2026 |
| 5.4.3 | 5 | 10/02/2026 |
| 5.4.2 | 7 | 10/02/2026 |
| 5.4.1 | 6 | 10/02/2026 |
| 5.4.0 | 6 | 10/03/2026 |
| 5.3.0 | 7 | 09/28/2026 |
| 5.2.1 | 5 | 10/02/2026 |
| 5.2.0 | 8 | 10/02/2026 |
| 5.2.0-beta2 | 4 | 10/02/2026 |
| 5.2.0-beta1 | 8 | 10/02/2026 |
| 5.1.1 | 5 | 10/02/2026 |
| 5.1.0 | 5 | 10/02/2026 |
| 5.0.1 | 5 | 10/02/2026 |
| 5.0.0 | 7 | 10/02/2026 |
| 5.0.0-beta1 | 7 | 10/02/2026 |
| 4.3.1 | 6 | 10/02/2026 |
| 4.3.0 | 4 | 10/02/2026 |
| 4.2.1 | 6 | 10/02/2026 |
| 4.2.0 | 5 | 10/02/2026 |
| 4.1.2 | 6 | 10/02/2026 |
| 4.1.1 | 7 | 10/02/2026 |
| 4.1.0 | 4 | 10/02/2026 |
| 4.0.1 | 6 | 10/03/2026 |
| 4.0.0 | 8 | 10/02/2026 |
| 4.0.0-beta2 | 6 | 10/02/2026 |
| 4.0.0-beta1 | 6 | 10/03/2026 |
| 3.0.5 | 5 | 10/03/2026 |
| 3.0.4 | 5 | 10/03/2026 |
| 3.0.3 | 6 | 10/02/2026 |
| 3.0.2 | 5 | 10/02/2026 |
| 3.0.1 | 6 | 10/03/2026 |
| 3.0.0 | 7 | 10/03/2026 |
| 2.3.2 | 6 | 10/02/2026 |
| 2.3.1 | 6 | 10/03/2026 |
| 2.3.0 | 5 | 10/03/2026 |
| 2.2.0 | 6 | 10/02/2026 |
| 2.1.5 | 7 | 10/03/2026 |
| 2.1.4 | 6 | 10/02/2026 |
| 2.1.3 | 6 | 10/03/2026 |
| 2.1.2 | 5 | 10/02/2026 |
| 2.1.1 | 4 | 10/02/2026 |
| 2.1.0 | 5 | 10/02/2026 |
| 2.0.3 | 6 | 10/02/2026 |
| 2.0.2 | 6 | 10/02/2026 |
| 2.0.1 | 6 | 10/02/2026 |
| 2.0.0 | 6 | 10/02/2026 |
| 2.0.0-beta7 | 6 | 10/02/2026 |
| 2.0.0-beta6 | 6 | 10/02/2026 |
| 2.0.0-beta5 | 7 | 10/04/2026 |
| 2.0.0-beta4 | 6 | 10/03/2026 |
| 2.0.0-beta3 | 6 | 10/03/2026 |
| 2.0.0-beta2 | 5 | 10/02/2026 |
| 2.0.0-beta1 | 6 | 10/02/2026 |
| 1.2.1 | 5 | 10/02/2026 |
| 1.2.0 | 7 | 10/02/2026 |
| 1.1.2 | 6 | 10/02/2026 |
| 1.1.1 | 6 | 10/02/2026 |
| 1.1.0 | 6 | 10/02/2026 |
| 1.1.0-beta2 | 7 | 10/03/2026 |
| 1.1.0-beta1 | 9 | 10/03/2026 |
| 1.0.2 | 7 | 10/03/2026 |
| 1.0.1 | 6 | 10/02/2026 |
| 1.0.0 | 5 | 10/02/2026 |
| 1.0.0-beta2 | 7 | 10/02/2026 |