繁体   English   中英

ASP.NET中如何实现搜索过滤 Core Web API

[英]How to implement search filter in ASP.NET Core Web API

在我的 ASP.NET Core-6 Web API 中,我有这两个型号:

public class Department
{
    public int Id { get; set; }
    public string DepartmentName { get; set; }
}

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string StaffNumber { get; set; }

    public int DepartmentId { get; set; }
    public Department Department { get; set; }
}

为了能够进行分页,我有这些类:

public class Result
{
    internal Result(bool succeeded, IEnumerable<string> errors)
    {
        Succeeded = succeeded;
        Errors = errors.ToArray();
    }

    public bool Succeeded { get; set; }
    public string[] Errors { get; set; }

    public static Result Success()
    {
        return new Result(true, new string[] { });
    }

    public static Result Failure(IEnumerable<string> errors)
    {
        return new Result(false, errors);
    }
}

public class PaginatedList<T>
{
    public List<T> Items { get; }
    public int PageIndex { get; }
    public int TotalPages { get; }
    public int TotalCount { get; }

    public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalPages = (int)Math.Ceiling(count / (double)pageSize);
        TotalCount = count;
        Items = items;
    }

    public bool HasPreviousPage => PageIndex > 1;
    public bool HasNextPage => PageIndex < TotalPages;

    public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize, CancellationToken cancellationToken)
    {
        var count = await source.CountAsync(cancellationToken);
        var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationToken);
        return new PaginatedList<T>(items, count, pageIndex, pageSize);
    }
}

我正在使用实体框架,这是最终代码:

public class GetAllEmployeesWithPaginationQuery : IRequestWrapper<PaginatedList<EmployeeDto>>
{
    public int DepartmentId { get; set; }
    public int PageNumber { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}

public class GetAllEmployeesWithPaginationQueryHandler : IRequestHandlerWrapper<GetAllEmployeesWithPaginationQuery, PaginatedList<EmployeeDto>>
{
    private readonly IApplicationDbContext _context;
    private readonly IMapper _mapper;

    public GetAllEmployeesWithPaginationQueryHandler(IApplicationDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public async Task<ServiceResult<PaginatedList<EmployeeDto>>> Handle(GetAllEmployeesWithPaginationQuery request, CancellationToken cancellationToken)
    {
        PaginatedList<EmployeeDto> list = await _context.Employees
            .Where(x => x.DepartmentId == request.DepartmentId)
            .OrderBy(o => o.Name)
            .ProjectToType<EmployeeDto>(_mapper.Config)
            .PaginatedListAsync(request.PageNumber, request.PageSize, cancellationToken);

        return list.Items.Any() ? ServiceResult.Success(list) : ServiceResult.Failed<PaginatedList<EmployeeDto>>(ServiceError.NotFound);
    }
}

我已成功完成分页,但需要使用以下字段进行排序和搜索筛选:FirstName、LastName、StaffNumber 和 DepartmentName。

我如何实现这一目标?

谢谢你。

声明一个QueryObject class,这个class映射你传入的查询

例如/api/SearchEmployees?firstName=mark&sortBy=name&isSortAscending=true&page=2&pageSize=10将被映射到这个 class

public class QueryObject
{
        public int? Id { get; set; }

        public string FirstName { get; set; }

       public string LastName {get;set;}

        public string Abbr { get; set; }

        public bool IsSortAscending { get; set; }

        public string SortBy { get; set; }

        public int Page { get; set; }

        public int? PageSize { get; set; }
}

//在你 controller 做这样的事情:

public List<Employee> GetEmployee(QueryObject query)
{
    var employees = _context.Employees.AsQueryable();

    if(!string.IsNullOrEmpty(query.FirstName))
    {
        employees = employees.Where(e => e.Name.Contains(query.Name));
    }

 var ColumnsMap = new Dictionary<string, Expression<Func<Province, object>>>
            {
                ["name"] = c => c.Name,
                ["abbr"] = c => c.
            };
      employees = employees.ApplyOrdering(query, ColumnsMap);

     //Do paging as you have done earlier

     return employees.ToList();
    }

    //This function orders based on the key and Expression Function You pass

        public static IQueryable<T> ApplyOrdering<T>(this IQueryable<T> query, QueryObject queryObj, Dictionary<string, Expression<Func<T, object>>> columnsMap)
        {
            if (string.IsNullOrWhiteSpace(queryObj.SortBy) || !columnsMap.ContainsKey(queryObj.SortBy))
                return query;

            return queryObj.IsSortAscending ? query.OrderBy(columnsMap[queryObj.SortBy]) : query.OrderByDescending(columnsMap[queryObj.SortBy]);
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM