ASP.NET Core中使用GraphQL - 第九章 在GraphQL中處理多對多關係
- ofollow,noindex" target="_blank">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