如何用LINQ为WPF DataGrid实现多动态条件搜索?
问题描述
我正在用C# WPF开发,DataGrid的数据从SQL Server读取后填充到自定义集合LIST_HAVALEHA中。
模型类定义:
public class HAVALEHA_MODEL { public double? NUMBER { get; set; } public string NAME { get; set; } public string CUST_NO { get; set; } public long? DATE_N { get; set; } public string TAH { get; set; } public string MOLAH { get; set; } public string SHARAYET { get; set; } public int? ANBAR { get; set; } public double? FNUMCO { get; set; } public double? MAS { get; set; } }
集合定义:
public List<HAVALEHA_MODEL> LIST_HAVALEHA { get; set; } = new List<HAVALEHA_MODEL>();
需求:实现DataGrid的动态搜索——用户填写任意字段(如编号、日期等)时,对应字段的查询条件自动生效,最终组合所有已填写字段的条件执行查询。
我之前写的代码逻辑错误,无法正常运行:
IEnumerable<HAVALEHA_MODEL> LINQ_SEARCH = null; if (!string.IsNullOrEmpty(CUST_N_FLD)) { LINQ_SEARCH = LIST_HAVALEHA.Where(x => !(x.NAME is null) && x.NAME.ToLowerInvariant().Contains(CUST_N_FLD.ToLowerInvariant())); } if (!string.IsNullOrEmpty(NUMBER_FLD)) { LINQ_SEARCH = LIST_HAVALEHA.Where(x => !(x.NUMBER is null) && x.NAME.ToLowerInvariant().Contains(NUMBER_FLD.Text.Trim().ToLowerInvariant())); } MY_Data_Ggrid.ItemsSource = LINQ_SEARCH.ToList();
解决方案
1. 核心问题分析
原代码存在三个关键错误:
- 每次条件判断都直接从原始集合重新筛选,而非基于之前的筛选结果叠加,导致最后只有最后一个条件生效
- 编号字段的匹配逻辑错误:误用
x.NAME匹配NUMBER_FLD,且数值类型不能直接用Contains做模糊匹配 - 未处理所有搜索字段为空的情况,此时
LINQ_SEARCH为null,调用ToList()会触发空引用异常
2. 修复后的代码实现
// 初始化为原始集合的可查询对象 IQueryable<HAVALEHA_MODEL> query = LIST_HAVALEHA.AsQueryable(); // 处理客户名称搜索(CUST_N_FLD对应NAME字段) if (!string.IsNullOrWhiteSpace(CUST_N_FLD)) { string searchText = CUST_N_FLD.Trim().ToLowerInvariant(); query = query.Where(x => x.NAME != null && x.NAME.ToLowerInvariant().Contains(searchText)); } // 处理编号搜索(NUMBER_FLD对应NUMBER字段,数值类型需先转换) if (!string.IsNullOrWhiteSpace(NUMBER_FLD.Text)) { if (double.TryParse(NUMBER_FLD.Text.Trim(), out double numberValue)) { // 精确匹配编号 query = query.Where(x => x.NUMBER.HasValue && x.NUMBER.Value == numberValue); // 若需模糊匹配编号,可转为字符串处理: // string numberStr = numberValue.ToString(); // query = query.Where(x => x.NUMBER.HasValue && x.NUMBER.Value.ToString().Contains(numberStr)); } } // 示例:处理客户编号CUST_NO搜索 if (!string.IsNullOrWhiteSpace(CUST_NO_FLD)) { string searchText = CUST_NO_FLD.Trim().ToLowerInvariant(); query = query.Where(x => x.CUST_NO != null && x.CUST_NO.ToLowerInvariant().Contains(searchText)); } // 示例:处理日期字段DATE_N(假设为时间戳格式) if (!string.IsNullOrWhiteSpace(DATE_N_FLD)) { if (long.TryParse(DATE_N_FLD.Trim(), out long dateTimestamp)) { query = query.Where(x => x.DATE_N.HasValue && x.DATE_N.Value == dateTimestamp); // 若需日期范围查询,可调整为: // query = query.Where(x => x.DATE_N.HasValue && x.DATE_N.Value >= startTs && x.DATE_N.Value <= endTs); } } // 绑定最终结果到DataGrid MY_Data_Ggrid.ItemsSource = query.ToList();
3. 关键优化点
- 条件叠加:每次筛选基于上一步的
query对象,确保多个条件同时生效 - 数值类型处理:先尝试将输入字符串转换为对应数值类型,避免格式错误;支持精确或模糊匹配两种模式
- 空值与空输入处理:用
string.IsNullOrWhiteSpace覆盖空格输入场景,同时判断模型字段是否为null,避免空引用异常 - 全空场景兼容:当所有搜索字段为空时,直接返回原始集合数据,不会触发异常
内容的提问来源于stack exchange,提问作者entityfrmwork
相关产品推荐
相关产品推荐

