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

如何用EF和LINQ筛选名称包含数组中字符串的记录?

解决EF Core LINQ表达式无法翻译的问题

问题原因

EF Core无法将strArray.Any(s => i.Name.Contains(s))这类嵌套表达式正确翻译成SQL语句——内存数组的Any操作结合实体属性的Contains方法,超出了EF Core默认的表达式翻译能力范围。

解决方案:手动构建OR过滤条件

通过表达式树拼接多个Name.Contains(s)的OR条件,让EF Core能正确生成对应的SQL LIKE查询。

步骤1:实现简单的PredicateBuilder辅助类

这个类用来拼接多个过滤条件:

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> False<T>() => _ => false;

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
    {
        var invokedRight = Expression.Invoke(right, left.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>(Expression.OrElse(left.Body, invokedRight), left.Parameters);
    }
}

步骤2:修改查询代码

在strArray不为空的分支中,用PredicateBuilder构建OR条件:

[HttpGet]
public async Task<IActionResult> GetContent([FromQuery] string[]? strArray)
{
    List<DynamicContentDTO> dynContentList;

    if (strArray == null)
    {
        dynContentList = await _context.DynamicContents
            .OrderBy(x => x.OrderIndex)
            .Select(d => new DynamicContentDTO(d))
            .ToListAsync();
    }
    else
    {
        var predicate = PredicateBuilder.False<DynamicContent>();
        foreach (var s in strArray)
        {
            var searchTerm = s; // 避免闭包捕获变量的问题
            predicate = predicate.Or(content => content.Name.Contains(searchTerm));
        }

        dynContentList = await _context.DynamicContents
            .OrderBy(x => x.OrderIndex)
            .Where(predicate)
            .Select(d => new DynamicContentDTO(d))
            .ToListAsync();
    }

    return Ok(dynContentList);
}

替代方案(EF Core 5.0+适用)

如果你使用的是EF Core 5.0及以上版本,可以尝试使用EF.Functions.Like替代Contains,部分场景下EF Core能直接翻译:

.Where(i => strArray.Any(s => EF.Functions.Like(i.Name, $"%{s}%")))

但手动构建OR条件的方式兼容性更强,适用于所有EF Core版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:45:19