如何在Where子句中用动态谓词实现多字段模糊搜索?
动态筛选EnumerableRowCollection中任意字段包含指定值的行
问题背景
需要将硬编码指定字段的筛选逻辑,改为使用字符串数组AllColumns中的动态字段名,筛选出任意指定字段值包含objSearch.SearchAllFields的行。
现有可运行的硬编码代码
if (objSearch.SearchAllFields != "") { rows = results.Where(x => new[] { x.Field<string>("Col1"), x.Field<string>("Col2"), x.Field<string>("Col3") }.Any(s => s.ToLowerInvariant().Contains(objSearch.SearchAllFields.ToLowerInvariant()))); }
尝试的无效动态写法
string[] AllColumns = objProp.Select(p => p.Name).ToArray(); if (objSearch.SearchAllFields != "") { rows = results.Where(x => AllColumns.Any(s => s.ToLowerInvariant().Contains(objSearch.SearchAllFields.ToLowerInvariant()))); }
原始数据
Col1 Col2 Col3 test abc pqr 2 abc 123 asd test xyz
期望筛选结果(搜索词为test时)
Col1 Col2 Col3 test abc pqr asd test xyz
错误原因
你写的动态代码逻辑错误:当前是判断字段名(比如"Col1"、"Col2")是否包含搜索词,而不是判断字段对应的实际值是否包含搜索词,所以无法得到正确结果。
正确实现方式
遍历AllColumns数组时,对每个字段名,获取当前行该字段的字符串值,再判断是否包含搜索词。同时要处理字段值为null的情况,避免空引用异常:
string[] AllColumns = objProp.Select(p => p.Name).ToArray(); string searchTerm = objSearch.SearchAllFields.ToLowerInvariant(); if (!string.IsNullOrEmpty(searchTerm)) { rows = results.Where(x => AllColumns.Any(colName => { // 获取当前行指定字段的值,转为字符串并处理null string fieldValue = x.Field<string>(colName)?.ToLowerInvariant(); return fieldValue != null && fieldValue.Contains(searchTerm); }) ); }
代码说明
- 提前将搜索词转为小写,避免重复转换提升性能
- 使用
string.IsNullOrEmpty替代空字符串判断,逻辑更严谨 - 对每个字段名,调用
x.Field<string>(colName)获取字段值,用?.处理null值,避免空引用异常 - 仅当字段值不为null且包含搜索词时,返回true
内容的提问来源于stack exchange,提问作者CHash
相关产品推荐
相关产品推荐

