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
相关产品推荐
相关产品推荐

