您的位置:首页 > 编程语言 > ASP

ASP.NET Core中使用GraphQL - 第九章 在GraphQL中处理多对多关系

2018-11-14 06:14 1136 查看

ASP.NET Core中使用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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐