You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EF+LINQ实现通配符搜索的更优实现方案咨询

你当前的写法可以实现需求,但存在两个可优化点:一是多搜索条件时代码重复度高,可读性差;二是即便搜索条件为空,三元判断逻辑仍会被带入表达式树,部分低版本EF生成的SQL会携带冗余的1=1判断,虽不影响执行结果,但性能和简洁性都有提升空间。

最优通用方案:封装WhereIf扩展方法

这是.NET生态中处理动态搜索条件的通用实现,兼具性能和简洁性:

第一步:实现通用扩展方法

using System.Linq.Expressions;

public static class QueryableExtensions
{
    /// <summary>
    /// 条件成立时才执行Where过滤
    /// </summary>
    /// <param name="source">待过滤的IQueryable数据源</param>
    /// <param name="condition">是否执行过滤的判断条件</param>
    /// <param name="predicate">过滤谓词</param>
    public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, bool condition, Expression<Func<T, bool>> predicate)
    {
        return condition ? source.Where(predicate) : source;
    }

    // 如果需要处理内存集合的过滤,可以再加IEnumerable版本的重载
    public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, bool condition, Func<T, bool> predicate)
    {
        return condition ? source.Where(predicate) : source;
    }
}

第二步:业务代码调用

data = data
    .WhereIf(!string.IsNullOrEmpty(searchCriteria1), p => p.field1.Contains(searchCriteria1))
    .WhereIf(!string.IsNullOrEmpty(searchCriteria2), p => p.field2.Contains(searchCriteria2));

优势

  • 代码简洁:多条件场景下不需要重复写三元判断或大量if块,维护成本低
  • 性能最优:条件不成立时完全不会将过滤逻辑加入表达式树,EF生成的SQL没有任何冗余判断,执行效率最高
  • 通用性强:不止可以处理字符串空值的判断,所有动态条件(比如数值范围、日期过滤等)都可以用这个扩展方法

进阶优化:针对字符串模糊搜索的专属扩展

如果你的业务中存在大量字符串包含查询的场景,可以再封装一层更简化的扩展,连Contains逻辑都不用重复写:

public static IQueryable<T> WhereContainsIfNotEmpty<T>(this IQueryable<T> source, string searchValue, Expression<Func<T, string>> fieldSelector)
{
    if (string.IsNullOrEmpty(searchValue))
        return source;
    
    // 动态构造 p => p.字段.Contains(searchValue) 的表达式
    var parameter = fieldSelector.Parameters[0];
    var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
    var fieldAccess = fieldSelector.Body;
    var searchConstant = Expression.Constant(searchValue, typeof(string));
    var containsCall = Expression.Call(fieldAccess, containsMethod, searchConstant);
    var predicate = Expression.Lambda<Func<T, bool>>(containsCall, parameter);
    
    return source.Where(predicate);
}

调用时更加简洁:

data = data
    .WhereContainsIfNotEmpty(searchCriteria1, p => p.field1)
    .WhereContainsIfNotEmpty(searchCriteria2, p => p.field2);

内容的提问来源于stack exchange,提问作者Hashan S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 16:45:04