ASP.NET Core中使用GraphQL - 第九章 在GraphQL中处理多对多关系
2018-11-14 06:14
1136 查看
ASP.NET Core中使用GraphQL
- ASP.NET Core中使用GraphQL - 第一章 Hello World
- ASP.NET Core中使用GraphQL - 第二章 中间件
- ASP.NET Core中使用GraphQL - 第三章 依赖注入
- ASP.NET Core中使用GraphQL - 第四章 GrahpiQL
- ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量
- ASP.NET Core中使用GraphQL - 第六章 使用EF Core作为持久化仓储
- ASP.NET Core中使用GraphQL - 第七章 Mutation
- ASP.NET Core中使用GraphQL - 第八章 在GraphQL中处理一对多关系
上一章中,我们介绍了如何在GraphQL中处理一对多关系,这一章,我们来介绍一下GraphQL中如何处理多对多关系。
我们继续延伸上一章的需求,上一章中我们引入了客户和订单,但是我们没有涉及订单中的物品。在实际需求中,一个订单可以包含多个物品,一个物品也可以属于多个订单,所以订单和物品之间是一个多对多关系。
为了创建订单和物品之间的关系,这里我们首先创建一个订单物品实体。
OrderItem
[Table("OrderItems")] public class OrderItem { public int Id { get; set; } public string Barcode { get; set; } [ForeignKey("Barcode")] public virtual Item Item { get; set; } public int Quantity { get; set; } public int OrderId { get; set; } [ForeignKey("OrderId")] public virtual Order Order { get; set; } }
创建完成之后,我们还需要修改
Order和
Item实体, 添加他们与
OrderItem之间的关系
Order
public class Order { public int OrderId { get; set; } public string Tag { get; set; } public DateTime CreatedAt { get; set; } public Customer Customer { get; set; } public int CustomerId { get; set; } public virtual ICollection<OrderItem> OrderItems { get; set; } }
Item
[Table("Items")] public class Item { [Key] public string Barcode { get; set; } public string Title { get; set; } public decimal SellingPrice { get; set; } public virtual ICollection<OrderItem> OrderItems { get; set; } }
修改完成之后,我们使用如下命令创建数据库迁移脚本,并更新数据库
dotnet ef migrations add AddOrderItemTable dotnet ef database update
迁移成功之后,我们可以添加一个新的
GraphQL节点,使用这个新节点,我们可以向订单中添加物品。为了实现这个功能,我们首先需要为
OrderItem实体添加它在
GraphQL中对应的类型
OrderItemType
OrderItemType
public class OrderItemType : ObjectGraphType<OrderItem> { public OrderItemType(IDataStore dateStore) { Field(i => i.ItemId); Field<ItemType, Item>().Name("Item").ResolveAsync(ctx => { return dateStore.GetItemByIdAsync(ctx.Source.ItemId); }); Field(i => i.Quantity); Field(i => i.OrderId); Field<OrderType, Order>().Name("Order").ResolveAsync(ctx => { return dateStore.GetOrderByIdAsync(ctx.Source.OrderId); }); } }
第二步,我们还需要创建一个
OrderItemInputType来定义添加
OrderItem需要哪些字段。
OrderItemInputType
public class OrderItemInputType : InputObjectGraphType { public OrderItemInputType() { Name = "OrderItemInput"; Field<NonNullGraphType<IntGraphType>>("quantity"); Field<NonNullGraphType<IntGraphType>>("itemId"); Field<NonNullGraphType<IntGraphType>>("orderId"); } }
第三步,我们需要在
InventoryMutation类中针对
OrderItem添加新的
mutation。
InventoryMutation
Field<OrderItemType, OrderItem>() .Name("addOrderItem") .Argument<NonNullGraphType<OrderItemInputType>>("orderitem", "orderitem input") .ResolveAsync(ctx => { var orderItem = ctx.GetArgument<OrderItem>("orderitem"); return dataStore.AddOrderItemAsync(orderItem); });
第四步,我们需要在
IDataStore接口中定义几个新的方法,并在
DataStore类中实现他们
IDataStore
Task<OrderItem> AddOrderItemAsync(OrderItem orderItem); Task<Order> GetOrderByIdAsync(int orderId); Task<IEnumerable<OrderItem>> GetOrderItemByOrderIdAsync(int orderId);
DataStore
public async Task<OrderItem> AddOrderItemAsync(OrderItem orderItem) { var addedOrderItem = await _context.OrderItems.AddAsync(orderItem); await _context.SaveChangesAsync(); return addedOrderItem.Entity; } public async Task<Order> GetOrderByIdAsync(int orderId) { return await _context.Orders.FindAsync(orderId); } public async Task<IEnumerable<OrderItem>> GetOrderItemByOrderIdAsync(int orderId) { return await _context.OrderItems .Where(o => o.OrderId == orderId) .ToListAsync(); }
第五步,我们来修改
OrderType类,我们希望查询订单的时候,可以返回订单中的所有物品
public class OrderType : ObjectGraphType<Order> { public OrderType(IDataStore dataStore) { Field(o => o.Tag); Field(o => o.CreatedAt); Field<CustomerType, Customer>() .Name("Customer") .ResolveAsync(ctx => { return dataStore.GetCustomerByIdAsync(ctx.Source.CustomerId); }); Field<OrderItemType, OrderItem>() .Name("Items") .ResolveAsync(ctx => { return dataStore.GetOrderItemByOrderIdAsync(ctx.Source.OrderId); }); } } }
最后我们还需要在
Startup类中注册我们刚定义的2个新类型
services.AddScoped<OrderItemType>(); services.AddScoped<OrderItemInputType>();
以上就是所有的代码修改。现在我们启动项目
首先我们先为之前添加的订单1, 添加两个物品
然后我们来调用查询Order的
query, 结果中订单中物品正确显示了。
本文源代码: https://github.com/lamondlu/GraphQL_Blogs/tree/master/Part%20IX
相关文章推荐
- ASP.NET Core中使用GraphQL - 第八章 在GraphQL中处理一对多关系
- ASP.NET Core中使用GraphQL - 第二章 中间件
- ASP.NET Core使用GraphQL第二章之中间件
- ASP.NET - 使用依赖关系注入在 ASP.NET Core 中编写干净代码
- 学习ASP.NET Core, 怎能不了解请求处理管道[5]: 中间件注册可以除了可以使用Startup之外,还可以选择StartupFilter
- C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理
- 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下)
- 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射
- Asp.Net Core中使用Newtonsoft.Json进行序列化处理解决返回值首字母小写
- 使用依赖关系注入在 ASP.NET Core 中编写干净代码
- ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量
- 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上)
- [转]使用依赖关系注入在 ASP.NET Core 中编写干净代码
- ASP.NET Core中使用GraphQL - 第七章 Mutation
- ASP.NET Core使用GraphQL第一章之Hello World
- ASP.NET Core中使用GraphQL - 第一章 Hello World
- ASP.NET Core中使用GraphQL - 第四章 GraphiQL
- 使用ASP.NET Core支持GraphQL -- 较为原始的方法
- ASP.NET Core中使用GraphQL - 第三章 依赖注入
- ASP.NET Core中使用GraphQL - 第六章 使用EF Core作为持久化仓储