如何使用 async Task<IActionResult> ?或者如何在我的 Asp.Net Core Web Api 中以异步方式 运行
How do I use async Task<IActionResult> ? Or How to run in async way in my Asp.Net Core Web Api
我正尝试以异步方式 运行 我的控制器操作。
如何使用异步任务?或者如何以异步方式运行
// Db context
public class DeptContext : DbContext
{
public LagerContext(DbContextOptions<LagerContext> options)
: base(options)
{
Database.Migrate();
}
public DbSet<Department> Departments { get; set; }
public DbSet<Product> Products { get; set; }
}
// 这是我的接口 IDepRepository
Task<Department> GetDepartmentWithOrWithoutProducts(int deptId, bool includeProducts);
// 还有我的存储库 class DepRepository
public class DepRepository : IDepRepository
{
private DeptContext db;
public DepRepository(DeptContext context)
{
db = context;
}
// I'am geting Department name with products or Without products
public async Task<Department> GetDepartmentWithOrWithoutProducts(int deptId, bool includeProducts)
{
if(includeProductss)
{
return await db.Departments.Include(c => c.Products).Where(s => s.deptId == deptId).SingleAsync();
}
return await db.Departments.Where(s => s.deptId == deptId).SingleAsync();
}
}
那么我现在应该如何在我的 Controller 中以异步方式进行操作:我试过如下但我不知道这样做是否正确:
我没有收到任何错误,但如果它是正确的方式,我不会...
using System.Threading.Tasks;
using System.Net;
using Microsoft.Data.Entity;
using Microsoft.EntityFrameworkCore;
[Route("api/departments")]
public class DepartmentsController : Controller
{
private IDeptRepository _deptInfoRepository;
public DepartmentsController(IDeptRepository deptInfoRepository)
{
_deptInfoRepository = deptInfoRepository;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetDepatment(int id, bool includeProducts = false)
{
var dept = _deptInfoRepository.GetDepartmentWithOrWithoutProducts(id, includeComputers);
if(dept == null)
{
return BadRequest();
}
if(includeProducts)
{
var depResult = new DepartmentDto() { deptId = dept.deptId, deptName = dept.deptName };
foreach(var department in dept.Products)
{
depResult.Products.Add(new ProductDto() { productId = department.productId, deptId = department.deptId, ProductName = department.ProductName });
}
return Ok(depResult);
}
var departmentWithoutProductResult = new DepartmentsWithoutProductsDto() { DeptId = dept.deptId, DeptName = dept.DeptName};
return Ok(departmentWithoutProductResult);
}
如何以异步方式获取我的控制器。我不知道将那些 await 和 ToListAsync() 放在哪里。提前致谢!
你不应该在已经准备好的results
列表上做任何await
。它已经包含所需的数据 - 还等什么?
您应该制作新的异步版本的 GetDepartments()
方法并在从存储库获取数据时等待:
var depEntities = await _depRepository.GetDepartmentsAsync();
我无法从您的代码中看出 GetDepartments returns 的数据类型。我的猜测是您正在使用 EF Core 和 GetDepartments returns DbSet 或针对 DbSet 的 LINQ 查询。如果是这种情况,那么在设置 depEntities 变量的行之后,该变量指向一个延迟对象(一个尚未计算的表达式树)。或者换句话说,实际查询还没有发送到数据库。当您遍历 depEntities(使用您的 foreach 循环)时,您正在导致实际的潜在 long-运行 工作发生(数据库访问)。这就是你想要等待的。所以,是的,您可以制作 GetDepartments 的异步版本,或者您也可以将代码更改为:
var depEntities = await _depRepository.GetDepartments().ToListAsync();
对 ToListAsync 的调用将枚举延迟对象并执行数据库访问。您的 return 语句只会 return 结果。在幕后,该方法实际上 return 在您的 await 语句中,并在您等待的工作完成后恢复。
最后一点.. 任何数据库异常都将发生在枚举延迟对象的位置。
应重命名界面以更好地显示意图。
public interface IDepRepository {
Task<Department> GetDepartmentWithOrWithoutProductsAsync(int deptId, bool includeProducts);
//...
}
这将相应地更新实施。由于该方法在异步调用后实际上没有使用任何东西,因此没有任何理由将该方法标记为异步。只是 return 任务。
public Task<Department> GetDepartmentWithOrWithoutProductsAsync(int deptId, bool includeProducts) {
if(includeProductss) {
return db.Departments.Include(c => c.Products).Where(s => s.deptId == deptId).SingleAsync();
}
return db.Departments.Where(s => s.deptId == deptId).SingleAsync();
}
然而,控制器操作需要等待任务,然后在任务完成后继续,因此该方法将被标记为异步。
[HttpGet("{id}")]
public async Task<IActionResult> GetDepatment(int id, bool includeProducts = false) {
var dept = await _deptInfoRepository.GetDepartmentWithOrWithoutProductsAsync(id, includeComputers);
if (dept == null) {
return BadRequest();
}
if (includeProducts) {
var depResult = new DepartmentDto() { deptId = dept.deptId, deptName = dept.deptName };
foreach (var department in dept.Products) {
depResult.Products.Add(new ProductDto() {
productId = department.productId,
deptId = department.deptId,
ProductName = department.ProductName
});
}
return Ok(depResult);
}
var departmentWithoutProductResult = new DepartmentsWithoutProductsDto() { DeptId = dept.deptId, DeptName = dept.DeptName};
return Ok(departmentWithoutProductResult);
}
我正尝试以异步方式 运行 我的控制器操作。 如何使用异步任务?或者如何以异步方式运行
// Db context
public class DeptContext : DbContext
{
public LagerContext(DbContextOptions<LagerContext> options)
: base(options)
{
Database.Migrate();
}
public DbSet<Department> Departments { get; set; }
public DbSet<Product> Products { get; set; }
}
// 这是我的接口 IDepRepository
Task<Department> GetDepartmentWithOrWithoutProducts(int deptId, bool includeProducts);
// 还有我的存储库 class DepRepository
public class DepRepository : IDepRepository
{
private DeptContext db;
public DepRepository(DeptContext context)
{
db = context;
}
// I'am geting Department name with products or Without products
public async Task<Department> GetDepartmentWithOrWithoutProducts(int deptId, bool includeProducts)
{
if(includeProductss)
{
return await db.Departments.Include(c => c.Products).Where(s => s.deptId == deptId).SingleAsync();
}
return await db.Departments.Where(s => s.deptId == deptId).SingleAsync();
}
}
那么我现在应该如何在我的 Controller 中以异步方式进行操作:我试过如下但我不知道这样做是否正确: 我没有收到任何错误,但如果它是正确的方式,我不会...
using System.Threading.Tasks;
using System.Net;
using Microsoft.Data.Entity;
using Microsoft.EntityFrameworkCore;
[Route("api/departments")]
public class DepartmentsController : Controller
{
private IDeptRepository _deptInfoRepository;
public DepartmentsController(IDeptRepository deptInfoRepository)
{
_deptInfoRepository = deptInfoRepository;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetDepatment(int id, bool includeProducts = false)
{
var dept = _deptInfoRepository.GetDepartmentWithOrWithoutProducts(id, includeComputers);
if(dept == null)
{
return BadRequest();
}
if(includeProducts)
{
var depResult = new DepartmentDto() { deptId = dept.deptId, deptName = dept.deptName };
foreach(var department in dept.Products)
{
depResult.Products.Add(new ProductDto() { productId = department.productId, deptId = department.deptId, ProductName = department.ProductName });
}
return Ok(depResult);
}
var departmentWithoutProductResult = new DepartmentsWithoutProductsDto() { DeptId = dept.deptId, DeptName = dept.DeptName};
return Ok(departmentWithoutProductResult);
}
如何以异步方式获取我的控制器。我不知道将那些 await 和 ToListAsync() 放在哪里。提前致谢!
你不应该在已经准备好的results
列表上做任何await
。它已经包含所需的数据 - 还等什么?
您应该制作新的异步版本的 GetDepartments()
方法并在从存储库获取数据时等待:
var depEntities = await _depRepository.GetDepartmentsAsync();
我无法从您的代码中看出 GetDepartments returns 的数据类型。我的猜测是您正在使用 EF Core 和 GetDepartments returns DbSet 或针对 DbSet 的 LINQ 查询。如果是这种情况,那么在设置 depEntities 变量的行之后,该变量指向一个延迟对象(一个尚未计算的表达式树)。或者换句话说,实际查询还没有发送到数据库。当您遍历 depEntities(使用您的 foreach 循环)时,您正在导致实际的潜在 long-运行 工作发生(数据库访问)。这就是你想要等待的。所以,是的,您可以制作 GetDepartments 的异步版本,或者您也可以将代码更改为:
var depEntities = await _depRepository.GetDepartments().ToListAsync();
对 ToListAsync 的调用将枚举延迟对象并执行数据库访问。您的 return 语句只会 return 结果。在幕后,该方法实际上 return 在您的 await 语句中,并在您等待的工作完成后恢复。
最后一点.. 任何数据库异常都将发生在枚举延迟对象的位置。
应重命名界面以更好地显示意图。
public interface IDepRepository {
Task<Department> GetDepartmentWithOrWithoutProductsAsync(int deptId, bool includeProducts);
//...
}
这将相应地更新实施。由于该方法在异步调用后实际上没有使用任何东西,因此没有任何理由将该方法标记为异步。只是 return 任务。
public Task<Department> GetDepartmentWithOrWithoutProductsAsync(int deptId, bool includeProducts) {
if(includeProductss) {
return db.Departments.Include(c => c.Products).Where(s => s.deptId == deptId).SingleAsync();
}
return db.Departments.Where(s => s.deptId == deptId).SingleAsync();
}
然而,控制器操作需要等待任务,然后在任务完成后继续,因此该方法将被标记为异步。
[HttpGet("{id}")]
public async Task<IActionResult> GetDepatment(int id, bool includeProducts = false) {
var dept = await _deptInfoRepository.GetDepartmentWithOrWithoutProductsAsync(id, includeComputers);
if (dept == null) {
return BadRequest();
}
if (includeProducts) {
var depResult = new DepartmentDto() { deptId = dept.deptId, deptName = dept.deptName };
foreach (var department in dept.Products) {
depResult.Products.Add(new ProductDto() {
productId = department.productId,
deptId = department.deptId,
ProductName = department.ProductName
});
}
return Ok(depResult);
}
var departmentWithoutProductResult = new DepartmentsWithoutProductsDto() { DeptId = dept.deptId, DeptName = dept.DeptName};
return Ok(departmentWithoutProductResult);
}