【问题标题】:Changing the output DTO (return value) of the GetAll method in an AsyncCrudAppService更改 AsyncCrudAppService 中 GetAll 方法的输出 DTO(返回值)
【发布时间】:2018-07-16 13:09:08
【问题描述】:

我在我的 AppServices 中使用 ABP 的 AsyncCrudAppService。这是我的界面:

public interface IAssetRequisitionAppService : IAsyncCrudAppService
    <AssetRequisitionDto, Guid, GetAllInput, AssetRequisitionDto, AssetRequisitionDto, AssetRequisitionDetailsDto>
{ }

还有服务:

public class AssetRequisitionAppService : AsyncCrudAppService
    <AssetRequisition, AssetRequisitionDto, Guid, GetAllInput, AssetRequisitionDto, AssetRequisitionDto, AssetRequisitionDetailsDto>, 
    IAssetRequisitionAppService
{
    public AssetRequisitionAppService(IRepository<AssetRequisition, Guid> repository) : base(repository)
    { }
}

现在,我相信所有这些标准 CRUD 方法都会返回默认类型(在我的例子中是 AssetRequisitionDto)。但是,我想做的是为 Get()GetAll() 方法返回不同的类型。

Get() 应该有一个更详细的 DTO,其中包含 Navigation 道具的子属性。但是GetAll() 应该有一个不那么详细的,只是为了填充一个表格。

有没有办法以某种方式覆盖返回类型?

【问题讨论】:

    标签: asp.net-mvc entity-framework-6 dto aspnetboilerplate application-layer


    【解决方案1】:

    是的,有某种方式

    // using Microsoft.AspNetCore.Mvc;
    
    [ActionName(nameof(GetAll))]
    public PagedResultRequestDto MyGetAll(PagedResultRequestDto input)
    {
        return input;
    }
    
    [NonAction]
    public override Task<PagedResultDto<UserDto>> GetAll(PagedResultRequestDto input)
    {
        return base.GetAll(input);
    }
    

    参考:https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2859

    【讨论】:

    • 嗯,我试过了,但我相信这些注释(ActionNameNonAction)在控制器代码中使用。我需要应用层的东西。虽然我也看到你在这里提到了 AspNetCore 库。我应该强调我的项目使用 MVC 模板。不是核心。
    • NonActionAttribute 在 MVC5 的 System.Web.Mvc 中。
    【解决方案2】:

    我注意到我最终还是需要更复杂的过滤方法。所以,我创建了我的自定义类型和方法。

    首先,我创建了我自己的GetAllInput 派生自PagedAndSortedResultRequestDto。它适用于我的大部分服务,因为我通常需要查询与员工和位置相关的数据:

    public class GetAllInput : PagedAndSortedResultRequestDto
    {
        public long? PersonId { get; set; }
        public long? LocationId { get; set; }
        public EEmployeeType? EmployeeType { get; set; }
    }
    

    之后,我为我的每项服务编写了一个GetAll 方法。它们都返回PagedResultDto&lt;&gt;,所以我可以在表示层中使用它的功能。下面是一个例子:

    //MovableAppService
    
        public PagedResultDto<MovableLineDto> GetAllLinesRelatedToUser(GetAllInput input)
        {
            Logger.Info("Loading all movables related to current user");
    
            IQueryable<Movable> queryable = null;
            if (input.PersonId.HasValue)
            {
                if (input.EmployeeType == EEmployeeType.Recorder)
                {
                    var recorder = _personRepository.GetAll()
                    .OfType<Employee>()
                    .FirstOrDefault(x => x.Id == input.PersonId);
                    var authorizedStorageIds = recorder.StoragesAuthorized.Select(y => y.Id);
    
                    queryable = _repository.GetAll()
                        .Where(x => authorizedStorageIds.Contains(x.StorageOfOriginId));
                }
                else if (input.EmployeeType == EEmployeeType.UnitManager)
                {
                    var locationCodes = _locationRepository.GetAll()
                        .Where(x => x.ManagerInChargeId == input.PersonId)
                        .Select(x => x.Code);
    
                    foreach (var code in locationCodes)
                    {
                        queryable = _locationRepository.GetAll()
                            .Where(x => x.Code.StartsWith(code))
                            .SelectMany(x => x.AssignmentDocs)
                            .SelectMany(x => x.Movements)
                            .OfType<Assignment>()
                            .Where(x => x.TimeOfReturn == null)
                            .Select(x => x.Asset)
                            .OfType<Movable>();
                        queryable = queryable.Concat(queryable);
                    }
                }
                else if (input.TenantIdsOversee.Count() > 0)
                {
                    var overseer = _personRepository.GetAll()
                        .OfType<Overseer>()
                        .FirstOrDefault(x => x.Id == input.PersonId);
                    var overseeingTenantIds = overseer.TenantsOversee.Select(y => y.Id);
    
                    queryable = _repository.GetAll()
                       .Where(x => overseeingTenantIds.Contains((int)x.TenantId));
                }
                else if (input.EmployeeType == EEmployeeType.Employee)
                {
                    queryable = _personRepository.GetAll()
                        .OfType<Employee>()
                        .Where(x => x.Id == input.PersonId)
                        .SelectMany(x => x.AssignmentDocs)
                        .SelectMany(x => x.Movements)
                        .OfType<Assignment>()
                        .Where(x => x.TimeOfReturn == null)
                        .Select(x => x.Asset)
                        .OfType<Movable>();
                }
            }
            var list = queryable.ToList()
                    .OrderBy(x => x.Category.Definition);
            var items = _objectMapper.Map<IReadOnlyList<MovableLineDto>>(list);
    
            return new PagedResultDto<MovableLineDto>(items.Count, items);
        }
    

    顺便说一句,亚伦的回答可能对 ASP.NET Core 项目有效。但是我的项目在 MVC EF6 中,所以这些注释对我不可用。

    现在我将此标记为答案,但如果有更优雅的方式,我很高兴看到,然后我会改变我的标记。

    【讨论】:

    • 您要求覆盖GetAll 的返回类型,而您的答案是创建一个不相关的方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    相关资源
    最近更新 更多