10 WORKING WITH DELETE REQUESTS
10 使用 DELETE 请求
Let’s start this section by deleting a child resource first. So, let’s modify the IEmployeeRepository interface:
让我们先删除子资源来开始本节。因此,让我们修改 IEmployeeRepository 接口:
using Entities.Models;
namespace Contracts
{
public interface IEmployeeRepository
{
IEnumerable<Employee> GetEmployees(Guid companyId, bool trackChanges);
Employee GetEmployee(Guid companyId, Guid id, bool trackChanges);
void CreateEmployeeForCompany(Guid companyId, Employee employee);
void DeleteEmployee(Employee employee);
}
}
The next step for us is to modify the EmployeeRepository class:
下一步是修改 EmployeeRepository 类:
public void DeleteEmployee(Employee employee) => Delete(employee);
After that, we have to modify the IEmployeeService interface:
之后,我们必须修改 IEmployeeService 接口:
using Shared.DataTransferObjects;
namespace Service.Contracts
{
public interface IEmployeeService
{
IEnumerable<EmployeeDto> GetEmployees(Guid companyId, bool trackChanges);
EmployeeDto GetEmployee(Guid companyId, Guid id, bool trackChanges);
EmployeeDto CreateEmployeeForCompany(Guid companyId, EmployeeForCreationDto employeeForCreation, bool trackChanges);
void DeleteEmployeeForCompany(Guid companyId, Guid id, bool trackChanges);
}
}
And of course, the EmployeeService class:
当然,还有 EmployeeService 类:
public void DeleteEmployeeForCompany(Guid companyId, Guid id, bool trackChanges)
{
var company = _repository.Company.GetCompany(companyId, trackChanges);
if (company is null) throw new CompanyNotFoundException(companyId);
var employeeForCompany = _repository.Employee.GetEmployee(companyId, id, trackChanges);
if (employeeForCompany is null)
throw new EmployeeNotFoundException(id);
_repository.Employee.DeleteEmployee(employeeForCompany);
_repository.Save();
}
Pretty straightforward method implementation where we fetch the company and if it doesn’t exist, we return the Not Found response. If it exists, we fetch the employee for that company and execute the same check, where if it’s true, we return another not found response. Lastly, we delete the employee from the database.
非常简单的方法实现,我们获取公司,如果它不存在,我们返回 Not Found 响应。如果存在,我们获取该公司的员工并执行相同的检查,如果为 true,则返回另一个 not found 响应。最后,我们从数据库中删除该员工。
Finally, we can add a delete action to the controller class:
最后,我们可以向 controller 类添加一个 delete作:
[HttpDelete("{id:guid}")]
public IActionResult DeleteEmployeeForCompany(Guid companyId, Guid id)
{
_service.EmployeeService.DeleteEmployeeForCompany(companyId, id, trackChanges: false);
return NoContent();
}
There is nothing new with this action. We collect the companyId from the root route and the employee’s id from the passed argument. Call the service method and return the NoContent() method, which returns the status code 204 No Content.
此作没有什么新内容。我们从根路由中收集 companyId,从传递的参数中收集员工的 ID。调用 service 方法并返回 NoContent() 方法,该方法返回状态代码 204 No Content。
Let’s test this:
我们来测试一下
https://localhost:5001/api/companies/14759d51-e9c1-4afc-f9bf-08d98898c9c3/employees/e06cfcc6-e353-4bd8-0870-08d988af0956
Excellent. It works great.
非常好。它效果很好。
You can try to get that employee from the database, but you will get 404 for sure:
你可以尝试从数据库中获取该员工,但你肯定会得到 404:
https://localhost:5001/api/companies/14759d51-e9c1-4afc-f9bf-08d98898c9c3/employees/e06cfcc6-e353-4bd8-0870-08d988af0956
We can see that the DELETE request isn’t safe because it deletes the resource, thus changing the resource representation. But if we try to send this delete request one or even more times, we would get the same 404 result because the resource doesn’t exist anymore. That’s what makes the DELETE request idempotent.
我们可以看到 DELETE 请求不安全,因为它会删除资源,从而更改资源表示形式。但是,如果我们尝试发送一次甚至多次此删除请求,我们将得到相同的 404 结果,因为资源不再存在。这就是 DELETE 请求具有幂等性的原因。
10.1 Deleting a Parent Resource with its Children
10.1 删除父资源及其子项
With Entity Framework Core, this action is pretty simple. With the basic configuration, cascade deleting is enabled, which means deleting a parent resource will automatically delete all of its children. We can confirm that from the migration file:
使用 Entity Framework Core,此作非常简单。使用基本配置时,启用了级联删除,这意味着删除父资源将自动删除其所有子资源。我们可以从迁移文件中确认:
So, all we have to do is to create a logic for deleting the parent resource.
因此,我们所要做的就是创建一个用于删除父资源的逻辑。
Well, let’s do that following the same steps as in a previous example:
好吧,让我们按照与上一个示例相同的步骤来执行此作:
using Entities.Models;
namespace Contracts
{
public interface ICompanyRepository
{
IEnumerable<Company> GetAllCompanies(bool trackChanges);
Company GetCompany(Guid companyId, bool trackChanges);
void CreateCompany(Company company);
IEnumerable<Company> GetByIds(IEnumerable<Guid> ids, bool trackChanges);
void DeleteCompany(Company company);
}
}
Then let’s modify the repository class:
然后让我们修改 repository 类:
public void DeleteCompany(Company company) => Delete(company);
Then we have to modify the service interface:
然后我们就得修改服务接口了:
using Shared.DataTransferObjects;
namespace Service.Contracts
{
public interface ICompanyService
{
IEnumerable<CompanyDto> GetAllCompanies(bool trackChanges);
CompanyDto GetCompany(Guid companyId, bool trackChanges);
CompanyDto CreateCompany(CompanyForCreationDto company);
IEnumerable<CompanyDto> GetByIds(IEnumerable<Guid> ids, bool trackChanges);
(IEnumerable<CompanyDto> companies, string ids) CreateCompanyCollection(IEnumerable<CompanyForCreationDto> companyCollection);
void DeleteCompany(Guid companyId, bool trackChanges);
}
}
And the service class:
而 service 类:
public void DeleteCompany(Guid companyId, bool trackChanges)
{
var company = _repository.Company.GetCompany(companyId, trackChanges);
if (company is null)
throw new CompanyNotFoundException(companyId);
_repository.Company.DeleteCompany(company);
_repository.Save();
}
Finally, let’s modify our controller:
最后,让我们修改我们的控制器:
[HttpDelete("{id:guid}")]
public IActionResult DeleteCompany(Guid id)
{
_service.CompanyService.DeleteCompany(id, trackChanges: false);
return NoContent();
}
And let’s test our action:
让我们测试一下我们的操作:
https://localhost:5001/api/companies/0AD5B971-FF51-414D-AF01-34187E407557
It works.
它有效。
You can check in your database that this company alongside its children doesn’t exist anymore.
您可以在数据库中检查这家公司及其子公司是否不再存在。
There we go. We have finished working with DELETE requests and we are ready to continue to the PUT requests.
好了。我们已经完成了 DELETE 请求的处理,并准备继续处理 PUT 请求。