系列导航及源代码
需求
本文我们继续来看查询过程中的另外一个需求:搜索。搜索的含义是目标字段的全部或者部分值匹配请求中的搜索条件,对应到数据库层面是Contains
逻辑。实现起来也很简单。
目标
实现包含搜索条件的查询。
原理与思路
实现搜索的方式和之前基本思路是一致的,这篇文章大概是这个系列到目前为止最直接和简单的了。
实现
直接修改上一篇里定义的GetTodoItemsWithConditionQuery
,添加一个Title
字段用于搜索:
GetTodoItemsWithConditionQuery.cs
using AutoMapper;
using AutoMapper.QueryableExtensions;
using MediatR;
using TodoList.Application.Common.Interfaces;
using TodoList.Application.Common.Mappings;
using TodoList.Application.Common.Models;
using TodoList.Domain.Entities;
using TodoList.Domain.Enums;
namespace TodoList.Application.TodoItems.Queries.GetTodoItems;
public class GetTodoItemsWithConditionQuery : IRequest<PaginatedList<TodoItemDto>>
{
public Guid ListId { get; set; }
public bool? Done { get; set; }
public string? Title { get; set; }
public PriorityLevel? PriorityLevel { get; set; }
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 10;
}
public class GetTodoItemsWithConditionQueryHandler : IRequestHandler<GetTodoItemsWithConditionQuery, PaginatedList<TodoItemDto>>
{
private readonly IRepository<TodoItem> _repository;
private readonly IMapper _mapper;
public GetTodoItemsWithConditionQueryHandler(IRepository<TodoItem> repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
public async Task<PaginatedList<TodoItemDto>> Handle(GetTodoItemsWithConditionQuery request, CancellationToken cancellationToken)
{
return await _repository
.GetAsQueryable(x => x.ListId == request.ListId
&& (!request.Done.HasValue || x.Done == request.Done)
&& (!request.PriorityLevel.HasValue || x.Priority == request.PriorityLevel)
&& (string.IsNullOrEmpty(request.Title) || x.Title!.Trim().ToLower().Contains(request.Title!.ToLower())))
.OrderBy(x => x.Title)
.ProjectTo<TodoItemDto>(_mapper.ConfigurationProvider)
.PaginatedListAsync(request.PageNumber, request.PageSize);
}
}
验证
启动Api
项目,执行查询TodoItem
的请求:
请求
响应
总结
对于“包含”类的搜索查询需要注意的是搜索条件的准确性,比如是否允许模糊大小写,是否采用前缀/后缀匹配,是否涉及到大数据量并且没有index的多条件搜索(一般在这种情况下,可能需要考虑Elasticsearch等非关系型数据库存储来完成搜索查询)。对于普通的场景,实现起来还是比较简单的,我们也可以定义一些Repository的辅助类方法来统一管理类似的需求。