ASP.NET Core中使用GraphQLhtml
上一章中,咱們介紹瞭如何在GraphQL中處理一對多關係,這一章,咱們來介紹一下GraphQL中如何處理多對多關係。git
咱們繼續延伸上一章的需求,上一章中咱們引入了客戶和訂單,可是咱們沒有涉及訂單中的物品。在實際需求中,一個訂單能夠包含多個物品,一個物品也能夠屬於多個訂單,因此訂單和物品之間是一個多對多關係。github
爲了建立訂單和物品之間的關係,這裏咱們首先建立一個訂單物品實體。數據庫
[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
之間的關係c#
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; } }
[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; } }
修改完成以後,咱們使用以下命令建立數據庫遷移腳本,並更新數據庫async
dotnet ef migrations add AddOrderItemTable dotnet ef database update
遷移成功以後,咱們能夠添加一個新的GraphQL
節點,使用這個新節點,咱們能夠向訂單中添加物品。爲了實現這個功能,咱們首先須要爲OrderItem
實體添加它在GraphQL
中對應的類型OrderItemType
code
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
須要哪些字段。htm
public class OrderItemInputType : InputObjectGraphType { public OrderItemInputType() { Name = "OrderItemInput"; Field<NonNullGraphType<IntGraphType>>("quantity"); Field<NonNullGraphType<IntGraphType>>("itemId"); Field<NonNullGraphType<IntGraphType>>("orderId"); } }
第三步,咱們須要在InventoryMutation
類中針對OrderItem
添加新的mutation
。中間件
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
類中實現他們blog
Task<OrderItem> AddOrderItemAsync(OrderItem orderItem); Task<Order> GetOrderByIdAsync(int orderId); Task<IEnumerable<OrderItem>> GetOrderItemByOrderIdAsync(int orderId);
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