Code samples used in this blog series have been updated to latest version of .NET Core (5.0.4) and GraphQL-Dotnet (4.2.0). Follow this link to get the updated samples.
Building a GraphQL end-point with a single entity ain't gonna cut it. In this post, we introduce two new entities for handling orders for a customer. The relationship between Customer and Order is one-to-many i.e. A customer can have one or many orders, whereas a particular order belongs to a single customer.
You can configure entity relationship following entity framework conventions. Entity framework will auto-create a one-to-many relationship between entities if one of the entity contains a collection property of the second entity. This property is known as a navigation property.
In Customer entity, you have Orders as a collection navigation property.
Most of the time, a navigation property of collection type is enough to declare a one-to-many relationship. However, it is suggested that you declare a fully defined relationship. To achieve that, on the second entity you define a foreign key property along with a reference navigation property
Following represents the Order entity where CustomerId is a foreign key and the Customer is a reference navigation property.
A property is considered a navigation property if the type it points to can not be mapped as a scalar type by the current database provider. - docs.microsoft.com
I've added two new ObjectGraphTypes for defining accessible fields of Order and Customer as followings,
To expose two new end-points for accessing all the customers and orders, I've registered two new fields of ListGraphType inside the GameStoreQuery as following,
Implementations of the newly added fetch methods inside Repository.cs are as following,
I've also threw in two additional methods for creating Customer and Order,
As you already guessed, we have two new DbSet<> in our ApplicationDbContext class,
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Item> Items { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Customer> Customers { get; set; }
}
Of course, you have to add these method signatures in your repository interface as well for abstraction and DI,
Remember the last post on mutation, you had to create a new InputObjectGraphType for Item in order to create side effects. Likewise, the followings are the InputObjectGraphType for Customer and Order.
To expose two new end-points for creating customer and order, I've added two new fields inside the GameStoreMutation as following,
Finally, we need to register all the types with the DI system. Newly created services registration inside ConfigureServices are as followings,
public void ConfigureServices(IServiceCollection services)
{
/* Code removed for brevity */
services.AddTransient<CustomerType>();
services.AddTransient<CustomerInput>();
services.AddTransient<OrderType>();
services.AddTransient<OrderInputType>();
/* Code removed for brevity */
}
Now, run the application and make sure you can access the newly added fields,
Comments