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

如何动态构建Or组合的Expression<Func<T,bool>>实现多子串搜索

解决方案

要实现多子串或原串的OR匹配,同时保留品牌ID过滤,需要通过动态构建表达式树组合多个Contains条件,具体实现如下:

完整实现代码

using System.Linq.Expressions;
using System.Collections.Generic;

public class ProductsSpecification : BaseSpecifcation<Product>
{
    public ProductsSpecification(ProductSpecParams productParams) : base(BuildFinalCriteria(productParams))
    {
    }

    private static Expression<Func<Product, bool>> BuildFinalCriteria(ProductSpecParams productParams)
    {
        // 1. 整理所有需要匹配的关键词:原串+拆分后的子串(自动去重)
        var searchTerms = new HashSet<string>();
        if (!string.IsNullOrEmpty(productParams.Search))
        {
            searchTerms.Add(productParams.Search.ToLower());
            foreach (var term in productParams.Search.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
            {
                searchTerms.Add(term.ToLower());
            }
        }

        // 2. 构建品牌过滤基础条件
        Expression<Func<Product, bool>> brandCriteria = x => !productParams.BrandId.HasValue || x.ProductBrandId == productParams.BrandId;

        // 无搜索关键词时直接返回品牌条件
        if (!searchTerms.Any())
        {
            return brandCriteria;
        }

        // 3. 构建搜索条件的OR组合
        Expression<Func<Product, bool>> searchCriteria = x => false;
        foreach (var term in searchTerms)
        {
            var currentTerm = term; // 避免闭包陷阱,确保每个表达式捕获独立的关键词
            Expression<Func<Product, bool>> termExpr = x => x.Name.ToLower().Contains(currentTerm);
            
            // 用OR合并当前关键词条件与已有的搜索条件
            searchCriteria = Expression.Lambda<Func<Product, bool>>(
                Expression.OrElse(searchCriteria.Body, termExpr.Body),
                searchCriteria.Parameters.Single()
            );
        }

        // 4. 合并搜索条件与品牌条件(AND关系)
        return Expression.Lambda<Func<Product, bool>>(
            Expression.AndAlso(searchCriteria.Body, brandCriteria.Body),
            searchCriteria.Parameters.Single()
        );
    }
}

核心细节说明

  • 关键词去重:用HashSet存储关键词,自动剔除重复项,避免生成冗余的匹配条件
  • 闭包陷阱处理:循环中通过currentTerm变量捕获当前迭代的关键词,防止所有表达式引用同一个变量导致逻辑错误
  • 表达式树拼接:通过Expression.OrElse组合多个搜索条件(实现sub1 || sub2 || sub3 || 原串),再用Expression.AndAlso与品牌过滤条件组合(实现(搜索条件) && (品牌条件))

内容的提问来源于stack exchange,提问作者x19

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:01:11