LINQ查询用string.Contains报错:LIKE谓词含无效转义字符
解决LINQ string.Contains生成无效LIKE转义字符的问题
问题根源
EF Core 8.0.0在将string.Contains转换为SQL LIKE语句时,错误生成了ESCAPE N''(空转义字符),而SQL Server不允许空字符串作为转义字符,因此抛出The invalid escape character "" was specified in a LIKE predicate异常。
解决建议
1. 改用EF.Functions.Like手动控制LIKE逻辑
放弃string.Contains,直接使用EF Core提供的EF.Functions.Like方法,明确指定转义字符或避免空转义:
if (!string.IsNullOrEmpty(value)) { // 若需要处理SQL通配符(%、_、[]),先转义特殊字符 var escapedValue = value .Replace("%", @"\%") .Replace("_", @"\_") .Replace("[", @"\[") .Replace("]", @"\]"); query = query.Where(c => EF.Functions.Like(c.Field, $"%{escapedValue}%", @"\") || EF.Functions.Like(c.FieldB, $"%{escapedValue}%", @"\") || c.FieldDocuments.Any(d => EF.Functions.Like(d, $"%{escapedValue}%", @"\"))); }
如果不需要处理通配符(允许用户输入的%/_直接作为通配符使用),可以省略转义步骤:
query = query.Where(c => EF.Functions.Like(c.Field, $"%{value}%") || EF.Functions.Like(c.FieldB, $"%{value}%") || c.FieldDocuments.Any(d => EF.Functions.Like(d, $"%{value}%")));
2. 检查自定义查询拦截器或翻译逻辑
排查共享NuGet包中的ApiContext是否存在自定义的DbCommandInterceptor、IQueryTranslationPostprocessor等扩展代码,确认是否有逻辑错误修改了LIKE语句的转义字符配置,导致生成空转义字符串。
3. 升级EF Core到最新补丁版本
EF Core 8.0.0存在已知的LIKE转义相关bug,后续发布的8.0.x补丁版本(如8.0.1及以上)已修复此问题。将所有相关EF Core包升级到最新8.x版本:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite" Version="8.0.10" />
4. 排查全局字符串配置
检查ApiContext的OnConfiguring方法,是否设置了可能影响字符串比较的全局配置(如UseCollation、自定义字符串转换器),这些配置可能干扰EF Core生成LIKE语句的逻辑。
内容的提问来源于stack exchange,提问作者Thomas Mendes
相关产品推荐
相关产品推荐

