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

Asp.Net Core EF报错:LINQ查询参数表达式求值异常解决问询

问题描述

我正在使用Entity Framework查询数据库,通过searchOne、searchTwo、searchThree、searchFour四个条件进行搜索,代码如下:

public async Task<List<ClassName>> Search(string searchOne, string searchTwo, string searchThree, string searchFour)
{
    if (!String.IsNullOrEmpty(searchOne) || !String.IsNullOrEmpty(searchTwo) || !String.IsNullOrEmpty(searchThree) || !String.IsNullOrEmpty(searchFour))
    {
        return await _context.Class.Include(x => x.ClassContainForeignKey)
            .OrderBy(x => x.ID)
            .Where(x => x.SearchOne.ToLower().Contains(String.IsNullOrEmpty(searchOne.ToLower()) ? "" : searchOne.ToLower())
            && x.SearchTwo.ToLower().Contains(String.IsNullOrEmpty(searchTwo.ToLower()) ? "" : searchTwo.ToLower())
            && x.SearchThree.ToLower().Contains(String.IsNullOrEmpty(searchThree.ToLower()) ? "" : searchThree.ToLower())
            && x.SearchFour.ToLower().Contains(String.IsNullOrEmpty(searchFour.ToLower()) ? "": searchFour.ToLower())).ToListAsync();
    }
    else
    {
        return await _context.Class.Include(x => x.ClassContainForeignKey).OrderBy(x => x.ID).ToListAsync();
    }
}

但代码无法正常运行,调试发现错误来自返回数据的代码段:

return await _context.Class.Include(x => x.ClassContainForeignKey)
            .OrderBy(x => x.ID)
            .Where(x => x.SearchOne.ToLower().Contains(String.IsNullOrEmpty(searchOne.ToLower()) ? "" : searchOne.ToLower())
            && x.SearchTwo.ToLower().Contains(String.IsNullOrEmpty(searchTwo.ToLower()) ? "" : searchTwo.ToLower())
            && x.SearchThree.ToLower().Contains(String.IsNullOrEmpty(searchThree.ToLower()) ? "" : searchThree.ToLower())
            && x.SearchFour.ToLower().Contains(String.IsNullOrEmpty(searchFour.ToLower()) ? "": searchFour.ToLower())).ToListAsync();

出现错误:

One or more errors occurred (An exception was thrown while attempting to evaluate a LINQ query parameter expression. See the inner exception for more information. To show additional information call 'DbContextOptionsBuilder.EnableSensitiveDataLogging'.)

现寻求帮助:

  1. 如何使用Entity Framework Core而非LINQ解决该异常问题?
  2. 如何通过单个if语句,使用Entity Framework Core实现多条件搜索?

解决方案

1. 修复异常问题(EF Core实现)

报错核心原因是在LINQ表达式中直接对可能为null的参数调用ToLower(),当searchOne这类参数为null时,searchOne.ToLower()会抛出空引用异常,而EF Core无法将这种运行时异常转换为SQL表达式。

正确做法是先在LINQ表达式外部处理参数,再构建查询:

public async Task<List<ClassName>> Search(string searchOne, string searchTwo, string searchThree, string searchFour)
{
    // 初始化基础查询
    var query = _context.Class.Include(x => x.ClassContainForeignKey).OrderBy(x => x.ID);

    // 逐个处理非空搜索条件,动态添加过滤
    if (!string.IsNullOrEmpty(searchOne))
    {
        var lowerSearchOne = searchOne.ToLower();
        query = query.Where(x => x.SearchOne.ToLower().Contains(lowerSearchOne));
    }
    if (!string.IsNullOrEmpty(searchTwo))
    {
        var lowerSearchTwo = searchTwo.ToLower();
        query = query.Where(x => x.SearchTwo.ToLower().Contains(lowerSearchTwo));
    }
    if (!string.IsNullOrEmpty(searchThree))
    {
        var lowerSearchThree = searchThree.ToLower();
        query = query.Where(x => x.SearchThree.ToLower().Contains(lowerSearchThree));
    }
    if (!string.IsNullOrEmpty(searchFour))
    {
        var lowerSearchFour = searchFour.ToLower();
        query = query.Where(x => x.SearchFour.ToLower().Contains(lowerSearchFour));
    }

    return await query.ToListAsync();
}

该方案优势:

  • 提前处理参数,避免空引用异常
  • EF Core可正确解析表达式,生成高效SQL
  • 逻辑拆分清晰,便于后续维护

2. 单个if语句实现多条件搜索

若需用单个if语句,可先安全预处理所有参数,再构建统一过滤条件:

public async Task<List<ClassName>> Search(string searchOne, string searchTwo, string searchThree, string searchFour)
{
    var query = _context.Class.Include(x => x.ClassContainForeignKey).OrderBy(x => x.ID);

    if (!string.IsNullOrEmpty(searchOne) || !string.IsNullOrEmpty(searchTwo) || !string.IsNullOrEmpty(searchThree) || !string.IsNullOrEmpty(searchFour))
    {
        // 安全处理参数,避免空引用
        var s1 = searchOne?.ToLower() ?? "";
        var s2 = searchTwo?.ToLower() ?? "";
        var s3 = searchThree?.ToLower() ?? "";
        var s4 = searchFour?.ToLower() ?? "";

        // 构建多条件过滤:参数为空则该条件自动生效(不过滤),否则执行匹配
        query = query.Where(x => 
            (string.IsNullOrEmpty(s1) || x.SearchOne.ToLower().Contains(s1))
            && (string.IsNullOrEmpty(s2) || x.SearchTwo.ToLower().Contains(s2))
            && (string.IsNullOrEmpty(s3) || x.SearchThree.ToLower().Contains(s3))
            && (string.IsNullOrEmpty(s4) || x.SearchFour.ToLower().Contains(s4)));
    }

    return await query.ToListAsync();
}

补充优化建议

若使用EF Core 5及以上版本,推荐用EF.Functions.Like替代ToLower().Contains(),可利用数据库索引优化查询性能,同时避免大小写转换的额外开销:

query = query.Where(x => EF.Functions.Like(x.SearchOne, $"%{searchOne}%"));

注意:Like的大小写匹配规则取决于数据库列的排序规则,若需强制不区分大小写,可调整对应列的排序规则为不区分大小写类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:37:51