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

时间:2017-06-12 17:32:39

标签: c# entity-framework asynchronous async-await n-tier-architecture

我目前正在开发的应用程序并不支持异步执行。 我的目标是使三层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;
}

您如何使此代码异步?

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

是否有必要&#34;冒泡&#34; 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());
}
  

&#39;任务&GT;&#39;不包含&#39;选择&#39;的定义没有扩展方法&#39;选择&#39;接受第一个类型&#39;任务&gt;&#39;可以找到。

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

2 个答案:

答案 0 :(得分:1)

异步确实需要全部或全部无效。如果您在调用堆栈的任何位置都有一个阻塞调用,那么您的可伸缩性或多或少gets ruined by that one thing

就实体框架而言,让数据层直接返回IQueryable<T>而不是返回列表可能很有用。这可以让您灵活地分批升级您的应用程序。

答案 1 :(得分:0)

  1. 您不必更改映射以使所有呼叫都异步。
  2. 您收到此错误&#39; 任务&gt;&#39;不包含&#39;选择&#39;的定义没有扩展方法&#39;选择&#39;接受第一个类型&#39;&#39;可以找到,因为你需要等待你的电话。
  3. public Task<IEnumerable<OrganisationModel>> GetOrganisations(int? organisationId, List<int> statusIds)
    {
        return (await _organisationRepository.GetOrganisations(organisationId, statusIds)).Select(m => m.ToModel());
    }
    
    1. 您应该将您的异步方法命名为GetOrganisationsAsync。
    2. 您还需要等待WebAPI层。它看起来像这样
    3.        [HttpGet]       
              public async Task<HttpResponseMessage> GetOrganisations(int? organisationId, [FromUri]int[] statusIds)
              {
                 return OK(await _businessObject.GetOrganisations(organisationId,statusIds));
              }