EF Core 2.0多列Contains过滤:数据库优先Patient实体姓名筛选
完善患者姓名多列过滤查询方案
Got it,我来帮你把这个按姓名筛选患者的查询逻辑补全。首先得考虑几个关键点:空值处理避免空引用异常、大小写不敏感的模糊匹配,还有支持**名、姓、全名(名+姓/姓+名)**的多维度筛选。
完整查询代码
// 先统一处理过滤词:转小写+去除空格+兜底空值,避免后续重复处理 var normalizedFilter = filter?.Trim().ToLower() ?? string.Empty; // 如果过滤词为空,直接返回全部(根据业务需求调整,也可以跳过过滤) if (string.IsNullOrEmpty(normalizedFilter)) { return await query.ToListAsync(); } var filteredPatients = await query .Where(p => // 匹配名:先判空再转小写匹配 (p.Forename != null && p.Forename.ToLower().Contains(normalizedFilter)) || // 匹配姓:同样先判空 (p.Surname != null && p.Surname.ToLower().Contains(normalizedFilter)) || // 匹配「名 姓」格式的全名 (p.Forename != null && p.Surname != null && $"{p.Forename.ToLower()} {p.Surname.ToLower()}".Contains(normalizedFilter)) || // 可选:匹配「姓 名」格式的全名(如果业务需要支持反向顺序搜索) (p.Forename != null && p.Surname != null && $"{p.Surname.ToLower()} {p.Forename.ToLower()}".Contains(normalizedFilter)) ) .ToListAsync();
关键细节解释
- 过滤词预处理:提前把
filter转小写、去除前后空格,还兜底了空值,这样后续查询里不用重复做这些操作,也避免filter为null时调用Contains()报错。 - 空值安全判断:每个字段(
Forename/Surname)都先判断不为null,再调用ToLower()和Contains(),防止出现NullReferenceException——毕竟数据库里的姓名字段可能允许为空。 - 多维度匹配:
- 单独匹配名或姓,满足用户只输入名/姓的场景;
- 匹配「名+空格+姓」的全名,满足输入完整姓名的场景;
- 可选的「姓+空格+名」匹配,如果业务需要支持用户输入反向顺序的全名(比如输入“Doe John”也能找到John Doe)。
可选优化(针对EF Core)
如果你用的是EF Core 5及以上版本,可以试试用EF.Functions.Like替代Contains(),某些场景下数据库层面的模糊匹配性能会更好:
// 替换其中的Contains逻辑,比如匹配名的部分可以改成: (p.Forename != null && EF.Functions.Like(p.Forename.ToLower(), $"%{normalizedFilter}%"))
不过要注意,这种写法同样需要转小写来保证大小写不敏感,除非你的数据库已经配置了大小写不敏感的排序规则。
内容的提问来源于stack exchange,提问作者umutesen
相关产品推荐
相关产品推荐

