在 N 层数据应用程序中使用异步

Using async in a N-Tier Data Application

我目前开发的应用不支持异步执行。 我的目标是制作一个三层的 n 层同步应用程序支持异步调用。

网络

[HttpPost("GetOrganisations")]
public OrganisationViewModel GetOrganisations([FromBody] GetOrganisationModel model)
{
    List<OrganisationModel> organisations = _organisationService.GetOrganisations(model?.Id, model?.StatusIds).ToList();

    return new OrganisationViewModel()
    {
        Organisations = organisations
    };
}

商业

public IEnumerable<OrganisationModel> GetOrganisations(int? organisationId, List<int> statusIds)
{
    return _organisationRepository.GetOrganisations(organisationId, statusIds).Select(m => m.ToModel()); //ToModel = Remapping to business model using extension
}

public static class OrganisationExtensions
{
    public static OrganisationEntity ToEntity(this OrganisationModel model)
    {
        if (model == null) return null;

        OrganisationEntity entity = Mapper.Map<OrganisationModel, OrganisationEntity>(model);

        return entity;
    }

    public static OrganisationModel ToModel(this OrganisationEntity entity)
    {
        if (entity == null) return null;

        OrganisationModel model = Mapper.Map<OrganisationEntity, OrganisationModel>(entity);

        model.StatusName = entity?.Status?.Name;

        return model;
    }
}

数据

public IEnumerable<OrganisationEntity> GetOrganisations(int? organisationId, List<int> statusIds)
{
    IQueryable<OrganisationEntity> organisations = DB.Organisation.Include("Status").OrderByDescending(d => d.Created).AsQueryable();

    if (organisationId != null && organisationId > 0)
    {
        organisations = organisations.Where(o => o.Id == organisationId);
    }

    if (statusIds != null && statusIds.Count > 0)
    {
        organisations = organisations.Where(o => statusIds.Contains(o.StatusId));
    }

    return organisations;
}

你如何使这段代码异步?

业务层中的映射扩展使这变得越来越困难。

是否有必要 "bubble up" async/await 调用一直向上?

让我试一试..

数据

public async Task<List<OrganisationEntity>> GetOrganisations(int? organisationId, List<int> statusIds)
{
    IQueryable<OrganisationEntity> organisations = DB.Organisation.Include("Status").OrderByDescending(d => d.Created).AsQueryable();

    if (organisationId != null && organisationId > 0)
    {
        organisations = organisations.Where(o => o.Id == organisationId);
    }

    if (statusIds != null && statusIds.Count > 0)
    {
        organisations = organisations.Where(o => statusIds.Contains(o.StatusId));
    }

    return await organisations.ToListAsync();
}

商业

public Task<IEnumerable<OrganisationModel>> GetOrganisations(int? organisationId, List<int> statusIds)
{
    return _organisationRepository.GetOrganisations(organisationId, statusIds).Select(m => m.ToModel());
}

'Task>' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'Task>' could be found.

我知道我可以很容易地在业务层等待结果,但那不是使用异步的错误方式吗?据我了解,我应该在 weblayer 等待结果,并在使用异步时以某种方式将数据模型映射到业务模型。

Async 确实需要全有或全无才能有效。如果您在调用堆栈的任何位置都有一个阻塞调用,则您的可扩展性或多或少 gets ruined by that one thing.

就 Entity Framework 而言,让您的数据层 return 直接 IQueryable<T> 而不是 return 列表可能更有用。这可以让您灵活地分批升级您的应用程序,而不是一次全部升级。

  1. 您不必更改映射即可使所有调用异步。
  2. 您收到此错误“Task>”不包含 'Select' 的定义并且找不到接受类型“”的第一个参数的扩展方法 'Select' 因为您需要等待电话。
public Task<IEnumerable<OrganisationModel>> GetOrganisations(int? organisationId, List<int> statusIds)
{
    return (await _organisationRepository.GetOrganisations(organisationId, statusIds)).Select(m => m.ToModel());
}
  1. 您应该将您的异步方法命名为 GetOrganisationsAsync。
  2. 您还需要在 WebAPI 层等待。它看起来像这样
       [HttpGet]       
        public async Task<HttpResponseMessage> GetOrganisations(int? organisationId, [FromUri]int[] statusIds)
        {
           return OK(await _businessObject.GetOrganisations(organisationId,statusIds));
        }