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