如何在C# LINQ查询中动态应用不同比较操作符?
动态LINQ过滤实现方案
核心思路
先提取目标过滤规则(操作符+值),再根据操作符类型动态给LINQ查询追加对应的过滤条件,确保EF能将表达式正确转换为SQL,避免客户端内存评估。
修改后的完整代码
// 获取ProductGroup对应的过滤规则,避免重复遍历filterList var productGroupFilter = filterList.FirstOrDefault(filter => filter.InternalName == "ProductGroup"); // 安全转换过滤值,防止无效输入抛出异常 int? productGroupFilterValue = null; if (productGroupFilter != null && int.TryParse(productGroupFilter.Value, out var parsedValue)) { productGroupFilterValue = parsedValue; } // 定义基础查询(不含动态过滤条件) var productsQuery = from artikel in impGgContext.ArtikelTable join wgober in impGgContext.WgoberTable on new { parameter1 = artikel.Wgober } equals new { parameter1 = wgober.Wg_Ogrp } select new Database.DTO.QueryResults { ProductId = artikel._Kenn, ProductNo = artikel.Nummer, ProductSearchName = artikel.Such_e, ProductName = artikel.Text_f.GetNameFromContainer(Convert.ToInt32(Enums.Language.English)), ProductGroupNo = artikel.Wgober, ProductGroupName = wgober.Langtxt.GetNameFromContainer(Convert.ToInt32(Enums.Language.English)), ProductStatusNo = artikel.Prodstat }; // 根据操作符动态追加过滤条件 if (productGroupFilterValue.HasValue && productGroupFilter != null) { switch (productGroupFilter.Operator) { case "Equals": productsQuery = productsQuery.Where(p => p.ProductGroupNo == productGroupFilterValue.Value); break; case "Greater than": productsQuery = productsQuery.Where(p => p.ProductGroupNo >= productGroupFilterValue.Value); break; case "Contains": // 数值类型需转字符串后执行包含判断,确保EF能生成对应SQL productsQuery = productsQuery.Where(p => p.ProductGroupNo.ToString().Contains(productGroupFilter.Value)); break; } } // 执行查询 var list = productsQuery.ToList();
关键细节说明
- 安全值转换:用
int.TryParse替代Convert.ToInt32,避免用户输入非数值内容时抛出异常。 - 动态条件追加:先定义基础查询,再通过
Where方法动态追加过滤逻辑,这种方式EF能正确解析表达式并生成对应SQL,不会触发客户端内存过滤。 - Contains处理:由于
ProductGroupNo是数值类型,直接使用Contains会报错,需先转换为字符串再执行包含判断,EF Core 3.0+版本支持该转换的SQL生成。
内容的提问来源于stack exchange,提问作者dns_nx
相关产品推荐
相关产品推荐

