我们继续延伸上一章的需求, 上一章中我们引入了客户和订单, 但是我们没有涉及订单中的物品. 在实际需求中, 一个订单可以包含多个物品, 一个物品也可以属于多个订单, 所以订单和物品之间是一个多对多关系.
为了创建订单和物品之间的关系, 这里我们首先创建一个订单物品实体.
- 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 IX
来源: https://www.cnblogs.com/lwqlun/p/9955901.html