最直接的模糊匹配用 where + contains,但需判空并注意大小写敏感;多字段搜索可用 any 简化;大数据量应下推数据库而非内存遍历。

用 Where + Contains 做基础模糊匹配最直接
绝大多数场景下,对 List<t></t> 做字符串字段的模糊搜索,直接用 LINQ 的 Where 配合 Contains 就够用。它对应 SQL 中的 LIKE '%xxx%' 语义,且对大小写敏感——这点容易被忽略。
常见错误是直接写 item.Name.Contains(keyword) 却没处理 null 或空字符串,运行时抛出 NullReferenceException。
- 务必先判空:
!string.IsNullOrEmpty(item.Name) && item.Name.Contains(keyword) - 如需忽略大小写,用
IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0,比ToLower().Contains()更安全、性能更好 -
Contains只支持子串匹配,不支持正则或通配符(如*、?)
需要前缀/后缀匹配时,别硬套 Contains
如果业务明确要求“以 XXX 开头”(如搜索用户名),用 StartsWith 比 Contains 更准确、性能也更高;同理,“以 XXX 结尾”用 EndsWith。它们同样要防 null,且默认区分大小写。
- 推荐写法:
!string.IsNullOrEmpty(item.Code) && item.Code.StartsWith(keyword, StringComparison.OrdinalIgnoreCase) - 避免写成
item.Code?.StartsWith(...) == true——?.在null时返回null,和true比较结果是false,逻辑没错但可读性差、易误读 - 数据库迁移时(比如将来换 Entity Framework Core),
StartsWith能更好映射为LIKE 'xxx%',而Contains可能触发全表扫描
多字段联合搜索怎么写才不啰嗦
用户输入一个关键词,想同时在姓名、邮箱、备注里搜,一行 Where 就能搞定,不用拆成多个 Or 条件拼接。
关键点在于:把所有待查字段统一提取、去空、转小写(或用 StringComparison),再用 Any 判断是否任一字段命中。
- 示例:
list.Where(x => new[] { x.Name, x.Email, x.Remark }.Any(s => !string.IsNullOrEmpty(s) && s.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0)) - 字段多时建议抽成方法,避免重复逻辑;但别过早抽象——3–4 个字段直接内联更清晰
- 注意
new[]数组每次调用都会分配内存,高频搜索场景可考虑预存字段访问器委托,但普通后台管理界面没必要
性能隐患:大数据量时别在内存里模糊查
List<t>.Where(...).ToList()</t> 是纯内存操作,数据量一旦超几千条,UI 就会卡顿,用户输个字等半秒——这不是代码逻辑问题,是架构选择错误。
- 真实项目中,搜索应尽早下推到数据库(如用 EF Core 的
Where+Contains),让 SQL Server / PostgreSQL 做索引加速 - 如果必须本地过滤(比如离线模式或配置项缓存),考虑预建
Dictionary<string list>></string>做分词倒排,或引入 LiteDB、SQLite 等嵌入式引擎 - 永远检查
Count()前是否已ToList()—— 对未执行的 LINQ 查询反复调用Count()会重复遍历集合
模糊查询看着简单,真正卡住人的往往是数据规模和大小写策略这两个点,动手前先想清楚:这数据到底该在内存里筛,还是该交给数据库。










