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

C# LINQ Contains方法求助:查询空集及语法错误解决

问题:C# LINQ Contains方法返回空集及替代方案

我在使用C# LINQ的Contains方法时遇到问题,现有代码可运行但返回空集。相关代码如下:

var query = _context.RegistrationCodes.Select(x => x);

if (request.OperatorId != null && request.OperatorId != Guid.Empty)
{
    var checkOperator = _context.Operators.Include(a => a.OperatorLevel).Include(a => a.City).Include("City.StateRegion.Country").FirstOrDefault(a => a.Id == request.OperatorId);

    List<String> Cities = new List<String>();

    if (checkOperator.OperatorLevel.Name == "City")
    {
        Cities = await _context.Cities
            .Where(a => (checkOperator.CityId) == (a.Id))
            .Select(a => a.Code)
            .ToListAsync();
    }

    else if (checkOperator.OperatorLevel.Name == "Regional")
    {
        Cities = await _context.Cities
            .Where(a => checkOperator.City.StateRegionId == a.StateRegionId)
            .Select(a => a.Code)
            .ToListAsync();
    }

    else if (checkOperator.OperatorLevel.Name == "National")
    {
        List<Guid> StateRegion = await _context.StateRegions
            .Where(a => checkOperator.City.StateRegion.CountryId == a.CountryId)
            .Select(a => a.Id)
            .ToListAsync();
    
        Cities = await _context.Cities
            .Where(a => StateRegion.Contains(a.StateRegionId))
            .Select(a => a.Code)
            .ToListAsync();
    }

    var nullableStrings = Cities.Cast<String?>().ToList();
    
    query = query.Where(a => nullableStrings.Contains(a.Code));
}

我尝试将条件改为query = query.Where(a => a.Code.Contains(nullableStrings))以对比nullableStrings和a.Code,但该写法报错:Error : Argument 1: cannot convert from 'System.Collections.Generic.List' to 'char'。我需要一个能替代query = query.Where(a => nullableStrings.Contains(a.Code));的有效方法。


排查与解决方案

原代码返回空集的可能原因

  • Cities集合为空:如果checkOperator对应的层级没有查询到任何城市Code,nullableStrings就是空集合,Contains自然返回空结果。
  • 字符串匹配不严格:数据库中Code的大小写、空格与Cities列表中的Code不一致,导致匹配失败。

替代方法1:数据库层面关联查询(推荐)

原代码先查询Code列表再做内存过滤,性能和可靠性不如直接在EF Core中做关联查询,避免内存与数据库的匹配差异:

var query = _context.RegistrationCodes.AsQueryable();

if (request.OperatorId != null && request.OperatorId != Guid.Empty)
{
    var checkOperator = await _context.Operators
        .Include(a => a.OperatorLevel)
        .Include(a => a.City)
        .Include(a => a.City.StateRegion)
        .Include(a => a.City.StateRegion.Country)
        .FirstOrDefaultAsync(a => a.Id == request.OperatorId);

    if (checkOperator != null)
    {
        query = checkOperator.OperatorLevel.Name switch
        {
            "City" => query.Where(rc => rc.Code == checkOperator.City.Code),
            "Regional" => query.Where(rc => _context.Cities.Any(c => c.StateRegionId == checkOperator.City.StateRegionId && c.Code == rc.Code)),
            "National" => query.Where(rc => _context.Cities.Any(c => c.StateRegion.CountryId == checkOperator.City.StateRegion.CountryId && c.Code == rc.Code)),
            _ => query
        };
    }
}

// 执行最终查询
var result = await query.ToListAsync();

替代方法2:修复原代码的匹配逻辑

如果必须使用内存列表的Contains,可以处理字符串匹配细节:

// 统一转成小写消除大小写差异,过滤掉null值
var normalizedCities = Cities.Select(c => c?.ToLowerInvariant()).Where(c => c != null).ToList();

// 过滤时先判断a.Code不为null,再统一格式匹配
query = query.Where(a => a.Code != null && normalizedCities.Contains(a.Code.ToLowerInvariant()));

错误写法的原因说明

a.Code.Contains(nullableStrings)逻辑完全错误:string.Contains()方法仅接受单个char或string参数,你传入了集合List<string?>,类型不匹配导致报错。正确逻辑是集合.Contains(元素),用来判断元素是否存在于集合中,你搞反了调用顺序。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:12:02