在 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 列表可能更有用。这可以让您灵活地分批升级您的应用程序,而不是一次全部升级。
- 您不必更改映射即可使所有调用异步。
- 您收到此错误“Task>”不包含 'Select' 的定义并且找不到接受类型“”的第一个参数的扩展方法 'Select' 因为您需要等待电话。
public Task<IEnumerable<OrganisationModel>> GetOrganisations(int? organisationId, List<int> statusIds)
{
return (await _organisationRepository.GetOrganisations(organisationId, statusIds)).Select(m => m.ToModel());
}
- 您应该将您的异步方法命名为 GetOrganisationsAsync。
- 您还需要在 WebAPI 层等待。它看起来像这样
[HttpGet]
public async Task<HttpResponseMessage> GetOrganisations(int? organisationId, [FromUri]int[] statusIds)
{
return OK(await _businessObject.GetOrganisations(organisationId,statusIds));
}
我目前开发的应用不支持异步执行。 我的目标是制作一个三层的 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 列表可能更有用。这可以让您灵活地分批升级您的应用程序,而不是一次全部升级。
- 您不必更改映射即可使所有调用异步。
- 您收到此错误“Task>”不包含 'Select' 的定义并且找不到接受类型“”的第一个参数的扩展方法 'Select' 因为您需要等待电话。
public Task<IEnumerable<OrganisationModel>> GetOrganisations(int? organisationId, List<int> statusIds) { return (await _organisationRepository.GetOrganisations(organisationId, statusIds)).Select(m => m.ToModel()); }
- 您应该将您的异步方法命名为 GetOrganisationsAsync。
- 您还需要在 WebAPI 层等待。它看起来像这样
[HttpGet] public async Task<HttpResponseMessage> GetOrganisations(int? organisationId, [FromUri]int[] statusIds) { return OK(await _businessObject.GetOrganisations(organisationId,statusIds)); }