我正在尝试在 .NET Core Web API 中为包含外键的数据库表创建 POST、PATCH 和 PUT 方法。我不确定问题是出在我的方法上还是出在我在 swagger 上测试我的方法的方式上。我对同一数据库上不包含外键的表的方法完美地工作。
我的数据库表托管在 SQL Server 上,并将 CustomerId 作为外键。当我在 Swagger 上测试 POST 方法时,收到 400 错误,指出“客户字段为必填项”。
我在Visual Studio中的POST方法如下:
[HttpPost]
public async Task<ActionResult<Order>> PostOrder(Order order)
{
if (_context.Orders == null)
{
return Problem("Entity set 'ecopowerdatabaseContext.Orders' is null.");
}
_context.Orders.Add(order);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (OrderExists(order.OrderId))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtAction("GetOrder", new { id = order.OrderId }, order);
}
我已通过请求正文进行修改,以包含引用的客户字段的所有信息,但是当我这样做时,我收到冲突错误,因为它尝试使用已存在的 ID 发布到客户表。
在填充订单之前,您必须先检索客户实体。
var customer = await _context.Customers.FirstOrDefaultAsync(c => c.CustomerId == order.CustomerId);
if(customer == null) {
return BadRequest();
}
order.Customer = customer;
所以,你可以像这样编辑你的方法:
[HttpPost]
public async Task<ActionResult<Order>> PostOrder(Order order)
{
if (_context.Orders == null)
{
return Problem("Entity set 'ecopowerdatabaseContext.Orders' is null.");
}
var customer = await _context.Customers.FirstOrDefaultAsync(c => c.CustomerId == order.CustomerId);
if(customer == null) {
return BadRequest();
}
order.Customer = customer;
_context.Orders.Add(order);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (OrderExists(order.OrderId))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtAction("GetOrder", new { id = order.OrderId }, order);
}
我找到了解决办法。如果我将订单的必填字段添加到我的方法的输入参数中,以便将它们显式输入到 Swagger 中各自单独的文本框中,那么问题似乎就得到了解决。而不是将订单对象作为输入参数 - 因为该对象尚不存在。然后,我在该方法内创建一个新的 Order 对象,并在将新订单对象传递给 Add() 方法之前分配所有必需的属性。正确的代码如下:
[HttpPost]
public async Task<ActionResult<Order>> PostOrder(short OrderId,
DateTime OrderDate, short CustomerId, string Address)
{
if (_context.Orders == null)
{
return Problem("Entity set 'ecopowerdatabaseContext.Orders'
is null.");
}
Order order = new Order();
order.OrderId = OrderId;
order.OrderDate = OrderDate;
order.CustomerId = CustomerId;
order.DeliveryAddress = Address;
_context.Orders.Add(order);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if(OrderExists(order.OrderId))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtAction("GetOrder", new { id = order.OrderId },
order);
}